### Start Game Server with One Line Source: https://github.com/kingston-csj/jforgame/wiki/Home This snippet shows how to start the game server using TcpSocketServerBuilder. Ensure ServerConfig and GameMessageFactory are properly configured. ```java TcpSocketServerBuilder.newBuilder() .bindingPort(HostAndPort.valueOf(ServerConfig.getInstance().getServerPort())) .setMessageFactory(GameMessageFactory.getInstance()) .setMessageCodec(new StructMessageCodec()) .setSocketIoDispatcher(new MessageIoDispatcher(ServerScanPaths.MESSAGE_PATH)) .build() .start(); ``` -------------------------------- ### Start Cross-Server Service Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-socket-parent/README.md Example of starting a cross-server service. This is treated as a special game server instance and can use any preferred message codec. ```java if (config.getCrossPort() > 0) { // 启动跨服服务 crossServer = TcpSocketServerBuilder.newBuilder().bindingPort(HostAndPort.valueOf(ServerConfig.getInstance().getCrossPort())) .setMessageFactory(GameMessageFactory.getInstance()) .setMessageCodec(new StructMessageCodec()) .setSocketIoDispatcher(new MessageIoDispatcher(ServerScanPaths.MESSAGE_PATH)) .build(); crossServer.start(); } ``` -------------------------------- ### Start Netty TCP Server Source: https://github.com/kingston-csj/jforgame/wiki/Examples This code snippet demonstrates how to start a Netty TCP server with default components. It configures the binding port, message factory, message codec, and socket I/O dispatcher. ```java TcpSocketServerBuilder.newBuilder().bindingPort(HostAndPort.valueOf(ServerConfig.getInstance().getServerPort())) .setMessageFactory(GameMessageFactory.getInstance()) .setMessageCodec(new StructMessageCodec()) .setSocketIoDispatcher(new MessageIoDispatcher(ServerScanPaths.MESSAGE_PATH)) .build() .start(); ``` -------------------------------- ### Server Startup Configuration (Socket/WebSocket) Source: https://github.com/kingston-csj/jforgame/blob/master/README_EN.md Build and start the TCP socket server using the provided builder pattern. Ensure the server port, message factory, codec, and dispatcher are correctly configured. ```java TcpSocketServerBuilder.newBuilder() .bindingPort(HostAndPort.valueOf(ServerConfig.getInstance().getServerPort())) .setMessageFactory(GameMessageFactory.getInstance()) .setMessageCodec(new StructMessageCodec()) .setSocketIoDispatcher(new MessageIoDispatcher(ServerScanPaths.MESSAGE_PATH)) .build() .start(); ``` -------------------------------- ### Build Mina TCP Socket Server Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-socket-parent/README.md Example of building a TCP socket server using the Mina framework. Ensure the correct imports and configurations are in place. ```java import jforgame.socket.mina.support.server.TcpSocketServerBuilder; socketServer = TcpSocketServerBuilder.newBuilder().bindingPort(HostAndPort.valueOf(ServerConfig.getInstance().getServerPort())) .setMessageFactory(GameMessageFactory.getInstance()) .setMessageCodec(new StructMessageCodec()) .setSocketIoDispatcher(new MessageIoDispatcher(ServerScanPaths.MESSAGE_PATH)) .build(); ``` -------------------------------- ### Build Netty WebSocket Server Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-socket-parent/README.md Example of building a WebSocket server using Netty. Note the change in the builder class name compared to TCP socket servers. ```java websocketServer = WepSocketServerBuilder.newBuilder().bindingPort(HostAndPort.valueOf(ServerConfig.getInstance().getServerPort())) .setMessageFactory(GameMessageFactory.getInstance()) .setMessageCodec(new StructMessageCodec()) .setSocketIoDispatcher(new MessageIoDispatcher(ServerScanPaths.MESSAGE_PATH)) .build(); ``` -------------------------------- ### Build Netty TCP Socket Server Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-socket-parent/README.md Example of building a TCP socket server using the Netty framework. This is a direct alternative to Mina with minimal code changes. ```java jforgame.socket.netty.support.server.TcpSocketServerBuilder socketServer = TcpSocketServerBuilder.newBuilder().bindingPort(HostAndPort.valueOf(ServerConfig.getInstance().getServerPort())) .setMessageFactory(GameMessageFactory.getInstance()) .setMessageCodec(new StructMessageCodec()) .setSocketIoDispatcher(new MessageIoDispatcher(ServerScanPaths.MESSAGE_PATH)) .build(); ``` -------------------------------- ### Event-Driven Model with Annotations Source: https://github.com/kingston-csj/jforgame/wiki/Examples Bind event types to business methods using @Listener and @EventHandler annotations. This example shows how to capture a LEVEL_UP event. ```java @Listener public class SkillListener { @EventHandler(value=EventType.LEVEL_UP) public void onPlayerLevelup(EventPlayerLevelUp levelUpEvent) { System.err.println(getClass().getSimpleName()+"捕捉到事件"+levelUpEvent); } } ``` -------------------------------- ### Initialize DataManager in Non-Spring Boot Environment Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-data-spring-boot-starter/README.md Manually construct and initialize ResourceOptions and DataManager when not using Spring Boot. This setup is for direct usage of the jforgame-data module. ```java ResourceOptions options = new ResourceOptions(); options.setLocation("csv/"); options.setSuffix(".csv"); options.setTableScanPath("org.jforgame.server.game.database.config"); options.setContainerScanPath("org.jforgame.server.game.database.config"); DataManager dataManager = new DataManager(options, dataReader); dataManager.init(); ``` -------------------------------- ### Server-Side RPC Handler Source: https://github.com/kingston-csj/jforgame/wiki/Examples This is an example of a server-side RPC request handler. It uses @MessageRoute and @RequestHandler annotations to define the message route and handle incoming requests. ```java // 服务端 import jforgame.socket.share.IdSession; import jforgame.socket.share.annotation.MessageRoute; import jforgame.socket.share.annotation.RequestHandler; @MessageRoute public class HelloMsgRoute { @RequestHandler public Object sayHello(IdSession session, int index, ReqHello request) { ResHello response = new ResHello(); response.setContent("hello, rpc"); response.setIndex(index); return response; } } ``` -------------------------------- ### Initialize and Connect WebSocket Client Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-demo/src/test/resources/h5/welcome.html Initializes the WebSocket client with the server URL and establishes a connection. Ensure the server is running at the specified address. ```javascript ws.init({ url: "localhost:9527/ws", }).connect(); ``` -------------------------------- ### Configure Message Codec Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-socket-parent/README.md Demonstrates how to configure different message codecs like JSON, Protobuf, or a custom StructMessageCodec. Choose the codec that best fits your needs. ```java new JsonCodec() ``` ```java new ProtobufMessageCodec() ``` ```java new StructMessageCodec() ``` -------------------------------- ### Client-Side RPC Communication (Sync, Async, Promise) Source: https://github.com/kingston-csj/jforgame/wiki/Examples This client-side code demonstrates synchronous, asynchronous (callback), and Promise-based RPC calls. It includes setting up the socket client and handling responses and errors. ```java // 客户端,同时支持同步模式、异步模式、Promise模式!! SocketIoDispatcher msgDispatcher = new SocketIoDispatcherAdapter() { @Override public void dispatch(IdSession session, Object message) { System.err.println("收到消息<-- " + message.getClass().getSimpleName() + "=" + JsonUtil.object2String(message)); } @Override public void exceptionCaught(IdSession session, Throwable cause) { cause.printStackTrace(); } }; SocketClient socketClient = new TcpSocketClient(msgDispatcher, GameMessageFactory.getInstance(), new StructMessageCodec(), hostPort); IdSession session = socketClient.openSession(); ResHello response = (ResHello) RpcMessageClient.request(session, new ReqHello()); System.out.println("rpc 消息同步调用"); System.out.println(response); RpcMessageClient.callBack(session, new ReqHello(), new RequestCallback() { @Override public void onSuccess(Object callBack) { System.err.println("rpc 消息异步调用"); ResHello response = (ResHello) callBack; System.err.println(response); } @Override public void onError(Throwable error) { System.out.println("----onError"); error.printStackTrace(); } }); // future可以实现嵌套调用,避免“回调地狱” RpcMessageClient.future(session, new ReqHello()).thenCompose(o -> { ResHello response2 = (ResHello) o; System.out.println("rpc 消息future调用"); System.out.println(response2); return RpcMessageClient.future(session, new ReqHello()); }).thenAccept(o -> { System.out.println("rpc 消息future调用,继续处理"); ResHello response3 = (ResHello) o; System.out.println(response3); }); ``` -------------------------------- ### Handle WebSocket Connection Open Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-demo/src/test/resources/h5/welcome.html Sets a message indicating that the WebSocket connection has been successfully established. This confirms the client is ready for communication. ```javascript ws.onopen = function (event) { var respMessage = document.getElementById("respMessage"); respMessage.value = "建立连接"; }; ``` -------------------------------- ### Add Protobuf Codec Dependency Source: https://github.com/kingston-csj/jforgame/wiki/Examples Include this dependency to use protobuf for client-server communication. It allows for annotation-based .proto file generation. ```xml io.github.jforgame jforgame-codec-protobuf 1.0.0 ``` -------------------------------- ### Add jforgame-data-spring-boot-starter Dependency Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-data-spring-boot-starter/README.md Include this dependency in your Spring Boot project to enable jforgame-data integration. ```xml io.github.jforgame jforgame-data-spring-boot-starter 2.0.0 ``` -------------------------------- ### Message Route Handling Source: https://github.com/kingston-csj/jforgame/blob/master/README_EN.md Implement a controller to handle incoming messages, routing requests to the appropriate business logic. ```java @MessageRoute public class LoginController { @RequestHandler public void reqAccountLogin(IdSession session, ReqAccountLogin request) { GameContext.loginManager.handleAccountLogin(session, request.getAccountId(), request.getPassword()); } } ``` -------------------------------- ### Query Data by Index Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-data-spring-boot-starter/README.md Retrieve all configuration records that share a common value for a specified index field. Useful for fetching grouped data. ```java // 查询type=1的所有分组数据 List itemDataList = GameContext.dataManager.queryByIndex(ItemData.class, "type", 1); ``` -------------------------------- ### jforgame Module Structure Source: https://github.com/kingston-csj/jforgame/blob/master/README_EN.md Overview of the jforgame project's modular design, detailing each component's purpose and its role within the framework. ```git jforgame ├── jforgame-commons -- Basic common utilities ├── jforgame-threadmodel -- Thread model; two implementations: Actor model & keyword-based dispatch. Actor is recommended to avoid uneven thread workload ├── jforgame-runtime -- Application runtime monitoring metrics (memory, threads, classes, etc.) ├── jforgame-socket-parent -- TCP Socket communication module, including IO gateway, message routing and session management; provides Netty and Mina implementations ├── jforgame-socket-api -- Base API interfaces for server & client ├── jforgame-socket-netty -- Netty implementation with WebSocket server & client support ├── jforgame-socket-mina -- Mina implementation (without WebSocket support) ├── jforgame-orm -- Game-server-oriented custom ORM library for conversion between database table records and POJO objects ├── jforgame-data -- Configuration data module, providing CSV/Excel/JSON loading, validation, hot reload and secondary cache support ├── jforgame-data-spring-boot-starter -- Spring Boot starter for jforgame-data, responsible for property binding and auto-configuration ├── jforgame-hotswap -- Supports business code hot replacement ├── jforgame-codec-parent -- Codec component for Socket communication ├── jforgame-codec-api -- Codec API interfaces ├── jforgame-codec-protobuf -- Protobuf codec implementation ├── jforgame-codec-struct -- Standard JavaBean reflection codec; advanced version supports heterogeneous collection element types ├── jforgame-demo -- Demo of basic game components and business modules | ├── cache -- Guava-based cache framework | ├── db -- Async data persistence for player and global data based on commons-persist and ORM | ├── listener -- Event-driven model | ├── doctor -- Dynamic code execution via Groovy or JDK Instrumentation for class method modification | ├── cross -- Basic communication foundation for cross-server matches/events | ├── game/gm -- In-game GM command system | ├── game/admin -- Operation & maintenance backend commands | ├── tools -- Helper utilities to simplify development | └── utils -- General utility classes ``` -------------------------------- ### Query Data by Unique Index Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-data-spring-boot-starter/README.md Retrieve a single configuration record based on a unique index. This is for fields that are guaranteed to have only one matching record. ```java // 查询type=1的所有分组数据 HeroLevelData heroLevelData = GameContext.dataManager.queryByUniqueIndex(HeroLevelData.class, "index_id_level", "1_1"); ``` -------------------------------- ### Configure jforgame-data Properties Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-data-spring-boot-starter/README.md Configure jforgame-data settings in your application.yml file, specifying scan paths for configuration tables and cache containers. ```yaml jforgame: data: ## 配置表实体扫描目录 tableScanPath: org.jforgame.server.game.database.config ## 二级缓存Container扫描目录 containerScanPath: org.jforgame.server.game.database.config ``` -------------------------------- ### Query Single Record by ID Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-data-spring-boot-starter/README.md Retrieve a single configuration record by its primary key (ID). Assumes GameContext.dataManager is initialized. ```java // 查询id=1的数据 ItemData itemData = GameContext.dataManager.queryById(ItemData.class, 1); ``` -------------------------------- ### Add Netty Network Framework Dependency Source: https://github.com/kingston-csj/jforgame/wiki/Home Include this dependency to use the Netty-based network framework for jforgame. ```xml io.github.jforgame jforgame-socket-netty 1.0.0 ``` -------------------------------- ### Add Struct Codec Dependency Source: https://github.com/kingston-csj/jforgame/wiki/Examples Include this dependency for automatic message encoding and decoding using Java reflection. This avoids the need for manual .proto file creation. ```xml io.github.jforgame jforgame-codec-struct 1.0.0 ``` -------------------------------- ### Jforgame Maven Dependencies Source: https://github.com/kingston-csj/jforgame/blob/master/README_EN.md Include these dependencies in your pom.xml to add Jforgame's socket and codec functionalities. ```xml io.github.jforgame jforgame-socket-netty latest io.github.jforgame jforgame-codec-struct latest ``` -------------------------------- ### Reload Configuration Tables Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-data-spring-boot-starter/README.md Hot-reload specified configuration tables to apply changes without restarting the application. Logs success and failure for each table. ```java for (String table : tables) { try { GameContext.dataManager.reload(table); succ.add(table); } catch (Exception e) { log.error("", e); failed.add(table); } } log.info("本次热更配置,成功为[{}],失败为[{}]", JsonUtil.object2String(succ), JsonUtil.object2String(failed)); ``` -------------------------------- ### Integrate CacheService for Data Retrieval Source: https://github.com/kingston-csj/jforgame/wiki/Examples To leverage the built-in caching system, integrate CacheService into your data management class. This automatically caches objects retrieved from the database. ```java public class PlayerManager extends CacheService ``` -------------------------------- ### Add DB Entity for Persistence Source: https://github.com/kingston-csj/jforgame/wiki/Examples To persist a DB entity like Player, make the class extend BaseEntity and annotate it with @Entity. Fields to be persisted should be annotated with @Column. Ensure at least one field is annotated with @Id for the primary key. ```java Player p = new Player(); p.setId(123456L); p.setName(); DbService.getInstance().add2Queue(player); ``` -------------------------------- ### Message Protocol Definition Source: https://github.com/kingston-csj/jforgame/blob/master/README_EN.md Define a message class for client-server communication, including metadata for module and command, and fields for data. ```java @MessageMeta(module = Modules.LOGIN, cmd = LoginDataPool.REQ_LOGIN) public class ReqAccountLogin implements Message { /** Account serial number */ private long accountId; private String password; } ``` -------------------------------- ### RPC Method Annotation Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-socket-parent/README.md Handles cross-server communication using method annotations, similar to how client messages are processed. The sender uses session.send, and the receiver uses @RequestHandler. ```java // 发送方 session.send(new ReqHello()); // 接收方 @RequestHandler public void onResHello(IdSession session, ResHello response) { // 处理逻辑 } ``` -------------------------------- ### Send Login Request via WebSocket Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-demo/src/test/resources/h5/welcome.html Sends a login request message over the WebSocket connection. This function checks for WebSocket support before sending binary data containing account credentials. ```javascript function sendMsg(msg) { //发送消息 if (window.WebSocket) { var msg = { accountId: "123", password: "admin", }; ws.sendBytes(PacketType.ReqAccountLogin, msg); } } ``` -------------------------------- ### RPC Future Mode Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-socket-parent/README.md Asynchronous RPC call using RpcMessageClient with Futures, enabling chained operations and avoiding callback hell. Use thenCompose for sequential async operations and thenAccept for final processing. ```java // future可以实现嵌套调用,避免“回调地狱” RpcMessageClient.future(session, new ReqHello()).thenCompose(o -> { ResHello response2 = (ResHello) o; System.out.println("rpc 消息future调用"); System.out.println(response2); return RpcMessageClient.future(session, new ReqHello()); }).thenAccept(o -> { System.out.println("rpc 消息future调用,继续处理"); ResHello response3 = (ResHello) o; System.out.println(response3); }); ``` -------------------------------- ### Access Secondary Cache Container Data Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-data-spring-boot-starter/README.md Retrieve data from a custom cache container, which extends the default container to provide specific access methods like getRewardBy. ```java // 获取二级缓存数据 QuestContainer container = GameContext.dataManager.queryContainer(QuestData.class, QuestContainer.class); Reward rewards = container.getRewardBy(1); System.out.println(JsonUtil.object2String(rewards)); ``` -------------------------------- ### Handle WebSocket Connection Close Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-demo/src/test/resources/h5/welcome.html Logs a message to the display area when the WebSocket connection is closed. This is useful for monitoring connection status. ```javascript ws.onclose = function (event) { var respMessage = document.getElementById("respMessage"); respMessage.value = respMessage.value + "\n断开连接"; }; ``` -------------------------------- ### Update DB Entity and Add to Queue Source: https://github.com/kingston-csj/jforgame/wiki/Examples When an attribute of a persisted object changes, update the attribute and then add the object back to the queue using DbService.getInstance().add2Queue() to persist the changes. ```java player.setLevel(100); DbService.getInstance().add2Queue(player); ``` -------------------------------- ### RPC Callback Mode Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-socket-parent/README.md Asynchronous RPC call using RpcMessageClient with a callback. The onSuccess method is invoked upon successful response, and onError handles any exceptions. ```java RpcMessageClient.callBack(session, new ReqHello(), new RequestCallback() { @Override public void onSuccess(Object callBack) { System.err.println("rpc 消息异步调用"); ResHello response = (ResHello) callBack; System.err.println(response); } @Override public void onError(Throwable error) { System.out.println("----onError"); error.printStackTrace(); } }); ``` -------------------------------- ### Handle Incoming WebSocket Messages Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-demo/src/test/resources/h5/welcome.html Processes messages received from the WebSocket server. Parses JSON data, updates a message display area, and handles command packets. ```javascript ws.onmessage = function (event) { var resp = JSON.parse(event.data); var respMessage = document.getElementById("respMessage"); respMessage.value = respMessage.value + "\n" + resp.msg; PacketType.handle(resp.cmd, resp.msg); }; ``` -------------------------------- ### RPC Request-Blocking Mode Source: https://github.com/kingston-csj/jforgame/blob/master/jforgame-socket-parent/README.md Synchronous RPC call using RpcMessageClient. The response is directly returned after the call completes. Ensure the session and request object are valid. ```java ResHello response = (ResHello) RpcMessageClient.request(session, new ReqHello()); System.out.println("rpc 消息同步调用"); System.out.println(response); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.