### 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.