- vừa được xem lúc

Ezyfox Server tập 1 - Hướng dẫn viết ứng dụng WS đơn giản

0 0 1

Người đăng: Bảo Ngô

Theo Viblo Asia

Dự án Ezyfox Server:

Đây là dự án miễn phí, mã nguồn mở của Youngmonkeys, một nhóm các developer của Việt Nam, nhằm tạo ra một framework dành cho việc phát triển các ứng dụng realtime như game server, WebSocket server một cách nhanh chóng. Hiện dự án đã được 543 stars và 94 forks trên Github.

Một số tính năng chính của Ezyfox Server:

  • Hỗ trợ Socket (TCP/UDP), WebSocket
  • IoC Container & Dependency Injection: Tương tự Spring, Ezyfox Server cũng hỗ trợ quản lý các bean, binding, code generation, v.v
  • Traffic Encryption: hỗ trợ mã hóa TLS để tăng độ bảo mật
  • Hỗ trợ nhiều Client SDKs: Web, Java, Android, iOS, Unity, React, C++, Flutter, v.v.
  • Hỗ trợ embedded container
  • Document: https://youngmonkeys.org/ezyfox-server/guides/get-started

Kiến trúc của Ezyfox Server:

Ezyfox Server hướng tới việc hỗ trợ chạy nhiều service trên một server node, do đó mỗi server sẽ bao gồm nhiều zone, mỗi zone sẽ chứa nhiều app và plugin. Chi tiết các bạn có thể xem thêm ở đây.

Các business logic thường chúng ta sẽ đặt vào các app. ezyfox-server-architecture.png

Viết ứng dụng WS đầu tiên bằng Ezyfox Embedded Server:

Đây là 1 ứng dụng nhỏ lắng nghe kết nối WebSocket từ phía client và trả về 1 response đơn giản. Trước mắt chúng ta chỉ cần 1 zone và 1 app là đủ. Link project here

Đầu tiên, hãy tạo 1 maven project. Thêm ezyfox-server-embedded vào pom.xml như sau:

<?xml version="1.0"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"> <modelVersion>4.0.0</modelVersion> <groupId>com.ezyfoxserver</groupId> <artifactId>simple-chat</artifactId> <version>1.0.0</version> <dependencies> <dependency> <groupId>com.tvd12</groupId> <artifactId>ezyfox-server-embedded</artifactId> <version>1.2.8.1</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.4</version> <scope>compile</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>com.spotify.fmt</groupId> <artifactId>fmt-maven-plugin</artifactId> <version>2.21.1</version> <executions> <execution> <goals> <goal>format</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
</project>

Tại package gốc, tạo package con app.support, chúng ta sẽ viết 2 class để khởi tạo app cho Ezyfox Server.

  1. Tạo class AppEntry kế thừa từ EzySimpleAppEntry. Đây là nơi chứa các callback để chúng ta manage các phase trong lifecycle của app. Chú yếu tôi chỉ log ra để xem Ezyfox Server có khởi tạo được app không:
public class AppEntry extends EzySimpleAppEntry { @Override protected void preConfig(EzyAppContext ctx) { logger.info("\n=================== APP START CONFIG ================\n"); } @Override protected void postConfig(EzyAppContext ctx) { logger.info("\n=================== APP END CONFIG ================\n"); } @Override public void start() { logger.info("start app"); } @Override protected String[] getScanablePackages() { return new String[] { "com.ezyfoxserver.app", }; }
}

Chú ý method getScanablePackages, chúng ta sẽ cung cấp những package chứa các managed bean để IoC container khởi tạo và quản lý chúng.

  1. Tạo AppEntryLoader kế thừa từ EzyAbstractAppEntryLoader:
public class AppEntryLoader extends EzyAbstractAppEntryLoader { @Override public EzyAppEntry load() { return new AppEntry(); }
}

Tại package gốc, tạo class ServerApplication chứa hàm main. Đây là entrypoint để start embedded server:

public class ServerApplication { public static void main(String[] args) throws Exception { EzyAppSettingBuilder appSettingBuilder = new EzyAppSettingBuilder().name("hello-world").entryLoader(AppEntryLoader.class); EzyZoneSettingBuilder zoneSettingBuilder = new EzyZoneSettingBuilder().name("example").application(appSettingBuilder.build()); EzySimpleSettings settings = new EzySettingsBuilder() .debug(true) .zone(zoneSettingBuilder.build()) .build(); EzyEmbeddedServer server = EzyEmbeddedServer.builder().settings(settings).build(); server.start(); }
}

Khởi chạy hàm main, chúng ta sẽ thấy đoạn log sau:

 ______ ________ ________ ______ __ _____ ______ _______ __ | ____|___ /\ \ / / ____/ __ \ \ / / | __ \| ____| /\ | __ \ \ / / | |__ / / \ \_/ /| |__ | | | \ V / ______ | |__) | |__ / \ | | | \ \_/ / | __| / / \ / | __|| | | |> < |______| | _ /| __| / /\ \ | | | |\ / | |____ / /__ | | | | | |__| / . \ | | \ \| |____ / ____ \| |__| | | | |______/_____| |_| |_| \____/_/ \_\ |_| \_\______/_/ \_\_____/ |_| 14:32:51.774 [main] DEBUG com.tvd12.ezyfoxserver.command.impl.EzyBroadcastEventImpl - broadcast server event: SERVER_READY
14:32:51.774 [main] DEBUG com.tvd12.ezyfoxserver.command.impl.EzyZoneBroadcastEventImpl - zone: example fire event: SERVER_READY

Có nghĩa là Ezyfox Server đã bootstrap thành công. Sử dụng postman để test WS: ws://localhost:2208/ws

ảnh.png

Viết 1 handler lắng nghe greet command từ client và phản hồi 1 lời chào:

  1. Tại package gốc, tạo package service và class Greeting bên trong:
@EzySingleton
public class Greeting { public String greet(String who) { return "Greet " + who + "!"; }
}
  1. Tại package gốc, tạo package event.handler và các handler bên trong:
@Setter
public abstract class AbstractClientRequestHandler extends EzyLoggable implements EzyHandler, EzyAppContextAware, EzySessionAware, EzyUserAware { protected EzyUser user; protected EzySession session; protected EzyAppContext appContext; @EzyAutoBind("appResponseFactory") protected EzyResponseFactory responseFactory; @Override public final void handle() { execute(); } protected abstract void execute() throws EzyBadRequestException;
}
@Setter
@EzyPrototype
@EzyObjectBinding(write = false)
@EzyRequestListener("greet")
public class GreetRequestHandler extends AbstractClientRequestHandler implements EzyDataBinding { private String who; @EzyAutoBind private Greeting greeting; @Override protected void execute() { responseFactory .newObjectResponse() .command("greet") .param("message", greeting.greet(who)) .session(session) .execute(); }
}

Class GreetRequestHandler sẽ lắng nghe WS command greet (chú ý @EzyRequestListener("greet"))từ client và phản hồi 1 response bằng responseFactory.

Quay lại class AppEntry và sửa method getScanablePackages:

 @Override protected String[] getScanablePackages() { return new String[] { "com.ezyfoxserver.app", "com.ezyfoxserver.event.handler", "com.ezyfoxserver.service", }; }

Ezyfox Server sẽ scan các bean trong package handlerservice.

OK, đến phần client:

Client là 1 html đơn giản, có sử dụng Jquery và Ezyclient viết bằng Javascript ảnh.png

Khi người dùng nhập tên vào và click connect, Ezyclient sẽ gọi các command HANDSHAKE, LOGIN, APP_ACCESSgreet theo thứ tự.

3 event đầu tiên sẽ được xử lý tự động bởi Ezyfox Server. Event greet sẽ được class GreetRequestHandler xử lý và trả về 1 lời chào, cái sẽ được hiển thị ở thẻ textarea.

<!doctype html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Hello EzyFox Server</title>
<style type="text/css">
.page-title { text-align: center;
} .container { border: 1px solid rgba(0, 0, 0, 0.8); text-align: center;
} .container textarea { width: 450px; height: 150px;
}
</style>
</head> <body>
<h1 class="page-title">Hello World Javascript Client</h1>
<div class="container"> <div class="connect"> <input type="text" id="url" value="ws://localhost:2208/ws"/> <input type="username" id="username" placeholder="your's name"/> <input type="submit" id="connect" value="Connect"/> </div> <div class="messages"> <textarea id="messages" disabled></textarea> </div> </div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="https://resources.tvd12.com/ezyclient-1.0.5.min.js"></script>
<script type="text/javascript"> var zoneName = "example";
var appName = "hello-world"; var log = function(msg) { var log = $('#log') log.append(msg + " \n").scrollTop(log[0].scrollHeight - log.height());
} var handshakeHandler = new EzyHandshakeHandler();
handshakeHandler.getLoginRequest = function(context) { return [zoneName, $('#username').val(), "123456", []];
} var userLoginHandler = new EzyLoginSuccessHandler();
userLoginHandler.handleLoginSuccess = function() { var accessAppRequest = [appName, []]; this.client.sendRequest(EzyCommand.APP_ACCESS, accessAppRequest);
} var accessAppHandler = new EzyAppAccessHandler();
accessAppHandler.postHandle = function(app, data) { app.sendRequest('greet', {who: app.client.me.name});
} var config = new EzyClientConfig;
config.zoneName = zoneName;
var clients = EzyClients.getInstance();
var client = clients.newDefaultClient(config);
var setup = client.setup; setup.addDataHandler(EzyCommand.HANDSHAKE, handshakeHandler);
setup.addDataHandler(EzyCommand.LOGIN, userLoginHandler);
setup.addDataHandler(EzyCommand.APP_ACCESS, accessAppHandler);
var setupApp = setup.setupApp(appName);
setupApp.addDataHandler("greet", function(app, data) { var message = data.message; $('#messages').val(message);
}); $(function () { $('#connect').click(function () { client.connect($('#url').val()); });
})
</script>
</body> </html>

Bình luận

Bài viết tương tự

- vừa được xem lúc

In app purchase trong Android (Phần 2)

Bài viết trước mình đã giới thiệu sơ lược về Google Billing Library và các setup môi trường. Trong bài viết này, chúng ta sẽ xem xét kỹ hơn vòng đời khi mua one-time product, cụ thể là quy trình bán và cấp cho người dùng mặt hàng kỹ thuật số mà họ đã mua trong ứng dụng của bạn.

0 0 60

- vừa được xem lúc

Những website tự học lập trình hiệu quả

Tự học lập trình để nâng cao kỹ năng luôn là nhu cầu thiết yếu của mỗi lập trình viên. Chẳng gì hơn khi tự mình tìm hiểu, trau dồi thêm kiến thức chuyên môn lập trình.

0 0 102

- vừa được xem lúc

Gluon Mobile: một framework tạo ứng dụng mobile đa nền tảng khác

Trong thế giới mobile thì React Native và Flutter quá là nổi tiếng trong việc hỗ trợ làm ứng dụng đa nền tảng vì thế là nó làm lu mờ đi phần nào các framework khác, Gluon có lẽ vì thế cũng cùng chung

0 0 20

- vừa được xem lúc

VARIABLES IN JAVA

This posts is introduce Types of variables in Java. . Local Variables. Instance Variables.

0 0 18

- vừa được xem lúc

15 JAVA CODING BEST PRACTICES CHO NGƯỜI MỚI

Ngay từ đầu, Java là một trong những ngôn ngữ lập trình thống trị. Trong thời đại tiến bộ ngày này, nơi mà nhiều ngôn ngữ mạnh mẽ có mặt đã chết từ lâu, Java vẫn phù hợp và phát triển nhanh chóng theo

0 0 56

- vừa được xem lúc

Custom Self-Hosted Maven Repository

Giới thiệu. Đối với một số ứng dụng sử dụng nhiều Micro Service bên trong, những Class, Function,.

0 0 33