Skip to content

Commit

Permalink
Tcp server
Browse files Browse the repository at this point in the history
  • Loading branch information
hxg2050 committed Jun 26, 2024
1 parent cad3350 commit 101c042
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 54 deletions.
43 changes: 43 additions & 0 deletions packages/server/src/BaseServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Socket } from "./socket";

export abstract class BaseServer<T = any> {
sockets = new Map<number, Socket>();
clients = new Map<number, T>();
uidSocketIds = new Map<number, number>()


handlerCallback?: ((client: Socket, data: string) => void) | undefined;

bindUid(uid: number, socket: Socket): void {
this.uidSocketIds.set(uid, socket.id)
}
unbindUid(uid: number): void {
this.uidSocketIds.delete(uid)
}

abstract send(socket: T, name: string | number, data: any): void;

sendTo(uid: number, name: string, data: any): void {
const tcpSocket = this.clients.get(uid);
if (!tcpSocket) {
return;
}
this.send(tcpSocket, name, data)
}
sendToUid(uid: number, name: string, data: any): void {
const socketId = this.uidSocketIds.get(uid)

if (!socketId) {
return;
}
this.sendTo(socketId, name, data)
}
reply(socketId: number, requestId: number, data: any): void {
const sws = this.clients.get(socketId);
if (!sws) {
return;
}
this.send(sws, requestId, data)
}

}
42 changes: 42 additions & 0 deletions packages/server/src/IServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Socket } from "./socket"

export interface IServer {

start(): void

handlerCallback?: (client: Socket, data: string) => void

/**
* 绑定uid
* @param uid
* @param socket
*/
bindUid(uid: number, socket: Socket): void
/**
* 解除用户绑定
* @param uid
*/
unbindUid(uid: number): void
/**
* 给指定id发送消息
* @param uid
* @param name
* @param data
*/
sendTo(uid: number, name: string, data: any): void
/**
* 给自定用户发送消息
* @param uid
* @param name
* @param data
*/
sendToUid(uid: number, name: string, data: any): void

/**
* 回复消息
* @param id
* @param requestId
* @param data
*/
reply(id: number, requestId: number, data: any): void;
}
11 changes: 7 additions & 4 deletions packages/server/src/feiyun.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { Socket } from './socket'
import { compose, type Middleware } from './compose'
import { Server } from './server'
import { IServer } from './IServer'

export interface ApplicationConfig {
host: string
port: number
customServer?: (config: ApplicationConfig) => IServer
}

export class Request {
Expand Down Expand Up @@ -33,14 +35,16 @@ export class Feiyun {
port: 3000,
}

public server!: Server
public server!: IServer

constructor(config: Partial<ApplicationConfig> = {}) {
this.config = { ...this.config, ...config }
}

listen() {
this.server = new Server(this.config)
this.server = this.config.customServer ? this.config.customServer(this.config) : new Server({
port: this.config.port
})
this.server.start()
this.server.handlerCallback = (client, data) => {
const ctx = new Context()
Expand Down Expand Up @@ -72,8 +76,7 @@ export class Feiyun {

async responseHandler(ctx: Context) {
if (ctx.response.data) {
ctx.socket.send(ctx.request.id, ctx.response.data);
// this.server.reply(ctx.socket.socket, ctx.request.id, ctx.response.data)
this.server.reply(ctx.socket.id, ctx.request.id, ctx.response.data)
}
}
}
81 changes: 46 additions & 35 deletions packages/server/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Socket } from './socket'
import { createWebsocketServer } from './ws'
import { SWS, WebSocketData, createWebsocketServer } from './ws'
import { IWebsocketServer } from './IWebsocketServer'
import { ServerWebSocket } from 'bun'
import { IServer } from './IServer'
type Handler = (msg: any, client: Socket) => Promise<any> | any


Expand All @@ -12,27 +12,23 @@ interface ServerConfig {
/**
* 服务器
*/
export class Server {
export class Server implements IServer {
handlers = new Map<string, Handler>()

clientIndex: number = 0

wss?: IWebsocketServer
wss?: IWebsocketServer<WebSocketData>

clients: Map<number, Socket> = new Map()
clientsFromServerWebSocket: Map<ServerWebSocket, Socket> = new Map();
clientsFromUid: Map<number, Socket> = new Map()
clientsFromServerWebSocket: Map<SWS, Socket> = new Map();

clients: Map<number, SWS> = new Map()
clientsFromUid: Map<number, number> = new Map()

/**
* 配置
* @param config 配置
*/
constructor(private config: ServerConfig) {
// this.wss = new WebSocketServer(config);
// this.wss.on('connection', (socket, request) => {
// this.onConnection(socket, request);
// });
// console.log('ws://127.0.0.1:' + config.port);
}

/**
Expand All @@ -43,8 +39,9 @@ export class Server {
port: this.config.port
});
this.wss.open((ws) => {
const client = new Socket(++this.clientIndex, this, ws)
this.clients.set(this.clientIndex, client)
const client = new Socket(this)
ws.data.socketId = client.id;
this.clients.set(this.clientIndex, ws)
this.clientsFromServerWebSocket.set(ws, client);
});
this.wss.message((ws, data) => {
Expand Down Expand Up @@ -77,36 +74,39 @@ export class Server {
this.handlers.set(path, handler)
}

unbindUid(uid: number): void {
this.clientsFromUid.delete(uid)
}

/**
* 发送消息到客户端
* @param sokcet
* @param name
* @param data
*/
// send(sokcet: Socket, name: string | number, data: any) {
// sokcet.send(JSON.stringify([1, name, data]))
// }
send(sokcet: SWS, name: string | number, data: any) {
sokcet.send(JSON.stringify([1, name, data]))
}

/**
* 发送消息到客户端(uid)
*/
sendToUid(uid: number, name: string, data: any) {
const socket = this.getByUid(uid);
if (!socket) {
return false

sendTo(id: number, name: string, data: any): void {
const sws = this.clients.get(id);
if (!sws) {
return;
}
socket.send(name, data)
return true
this.send(sws, name, data)
}

/**
* 给客户端回复消息
* @param socket
* @param id
* @param data - 内容
* 发送消息到客户端(uid)
*/
reply(socket: Socket, id: number, data: any) {
socket.send(id, data)
sendToUid(uid: number, name: string, data: any) {
const socketId = this.clientsFromUid.get(uid)

if (!socketId) {
return;
}
this.sendTo(socketId, name, data)
}

/**
Expand All @@ -115,7 +115,7 @@ export class Server {
* @param socket
*/
bindUid(uid: number, socket: Socket) {
this.clientsFromUid.set(uid, socket);
this.clientsFromUid.set(uid, socket.id);
}

/**
Expand All @@ -131,8 +131,19 @@ export class Server {
* 获取在线状态
*/
isOnline(uid: number) {
const socket = this.getByUid(uid);
return socket?.socket.readyState === 1
const socket = this.clients.get(uid);
return socket?.readyState === 1
}

/**
* 给客户端回复消息
*/
reply(socketId: number, requestId: number, data: any) {
const sws = this.clients.get(socketId);
if (!sws) {
return;
}
this.send(sws, requestId, data)
}

isDebug = false
Expand Down
27 changes: 20 additions & 7 deletions packages/server/src/socket.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import { ServerWebSocket } from 'bun'
import type { Server } from './server'
import { IServer } from './IServer';

const createId = (() => {
let id = 0
return () => {
return ++ id;
}
})();

export class Socket {
constructor(public id: number, public server: Server, public socket: ServerWebSocket) {
id = createId();

constructor(public server: IServer) {

}

Expand All @@ -29,9 +37,14 @@ export class Socket {
/**
* 发送消息
*/
send(name: number, data?: any): void
send(name: string, data?: any): void
send(name: string | number, data?: any) {
this.socket.send(JSON.stringify([1, name, data]))
send(name: string, data?: any) {
this.server.sendTo(this.id, name, data);
}

/**
* 断开链接
*/
close() {

}
}
43 changes: 43 additions & 0 deletions packages/server/src/tcp/TcpServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { BaseServer } from "../BaseServer";
import { IServer } from "../IServer";
import { Socket } from "../socket";
import { Socket as TcpSocket } from "bun";

type SocketData = { socketId: number };

export class TcpServer extends BaseServer<TcpSocket<SocketData>> implements IServer {

constructor(public port: number) {
super();
}

start(): void {
Bun.listen<SocketData>({
hostname: "0.0.0.0",
port: this.port,
socket: {
open: (socket) => {
const client = new Socket(this)
socket.data.socketId = client.id;
this.clients.set(client.id, socket)
this.sockets.set(client.id, client);
},
data: (socket, data) => {
const client = this.sockets.get(socket.data.socketId)!;
try {
this.handlerCallback?.(client, data.toString())
} catch (error) {
console.error(error)
}
},
close: (socket) => {
this.sockets.delete(socket.data.socketId);
}
},
});
}

send(socket: TcpSocket<SocketData>, name: string | number, data: any): void {
socket.write(JSON.stringify([1, name, data]));
}
}
Loading

0 comments on commit 101c042

Please sign in to comment.