Asynchronous Network Message Processing Framework and asynchronous message framework
Recently, the original kendynet network framework has been rewritten most of the Code, making the provided interfaces clearer and user-friendly.
The entire framework has three layers of architecture:
1) A single thread, a network interface based on the original data stream, does not provide packet processing and timer events at this layer. Users can perform further encapsulation based on their own needs.
2) A single thread provides connection, packet processing, and receive sending timeout processing.
3) The Asynchronous Network Framework with logical network separation abstracts three main types: asynnet_t, sock_ident, and msgdisp_t.
Asynnet_t: network processing engine. When you create an instance, you can input the pollercount parameter, in which each poller runs in a separate thread.
Sock_ident: encapsulation of logic layer operations, which can be safely used in multi-threaded environments.
Msgdisp_t: Message splitter. Each splitter has a message queue to receive messages transmitted from network threads.
Msgdisp_t provides two usage modes:
First: typical thread pool mode. In this mode, you can create a message splitter. Multiple logic threads call this message splitter.
Msg_loop.
Second: shared network layer mode. Start N threads in a process, and each thread runs a different service. All these services share the network communication layer.
In this case, network messages need to be routed to the correct service. You can create a message splitter for each thread, and each thread is on its own message splitter.
Call msg_loop to process only your own messages.
The following is an example of an Asynchronous Network Server:
#include <stdio.h>#include <stdlib.h>#include "core/msgdisp.h"#include "testcommon.h"uint32_t recvsize = 0;uint32_t recvcount = 0;///int32_t asynnet_bind(msgdisp_t disp,sock_ident sock,void *ud,int8_t raw,uint32_t send_timeout,uint32_t recv_timeout)void asynconnect(msgdisp_t disp,sock_ident sock,const char *ip,int32_t port){ printf("asynconnect\n"); disp->bind(disp,sock,1,0,30*1000);}void asynconnected(msgdisp_t disp,sock_ident sock,const char *ip,int32_t port){ printf("asynconnected\n"); ++client_count;}void asyndisconnected(msgdisp_t disp,sock_ident sock,const char *ip,int32_t port,uint32_t err){ --client_count;}int32_t asynprocesspacket(msgdisp_t disp,sock_ident sock,rpacket_t rpk){ recvsize += rpk_len(rpk); recvcount++; asyn_send(sock,wpk_create_by_other((struct packet*)rpk)); return 1;}void asynconnectfailed(msgdisp_t disp,const char *ip,int32_t port,uint32_t reason){}int main(int argc,char **argv){ setup_signal_handler(); InitNetSystem(); asynnet_t asynet = asynnet_new(1); msgdisp_t disp = new_msgdisp(asynet, asynconnect, asynconnected, asyndisconnected, asynprocesspacket, asynconnectfailed); int32_t err = 0; disp->listen(disp,argv[1],atoi(argv[2]),&err); uint32_t tick,now; tick = now = GetSystemMs(); while(!stop){ msg_loop(disp,50); now = GetSystemMs(); if(now - tick > 1000) { uint32_t elapse = now-tick; recvsize = (recvsize/elapse)/1000; printf("client_count:%d,recvsize:%d,recvcount:%d\n",client_count,recvsize,recvcount); tick = now; packet_send_count = 0; recvcount = 0; recvsize = 0; } } CleanNetSystem(); return 0;}
Project code in: https://github.com/sniperHW/luanet
Currently, only network support for linux and tcp is implemented. This part of code will be improved in the future and user-level thread-based RPC support will be provided.