当前位置: 首页 > Web前端 > vue.js

一个TCP长连接设备管理后台项目(二)

时间:2023-03-31 19:43:47 vue.js

后端模型图BTA(A端)-->TCPServerB(B端)-->TCPServerC(C端)-->TCPServerTCPServer-->PostgresqlPostgresql-->HTTPServerHTTPServer-->D(ClientA)HTTPServer-->E(ClientB)HTTPServer-->F(ClientC)后端需要设计两台服务器,一台TCP,一台HTTP。TCP主要处理与终端的长期连接交互。一个TCP连接对应一个终端设备,终端设备的唯一标识使用IMEI。HTTP处理与前端的交互。前端需要获取所有可用终端设备的列表,并向指定终端发送命令。因此,为了方便的从ip中找到对应的终端,进而从对应的终端中找到对应的conn,我们需要维护一个map:seqNumuint16phoneNumstringConnnet.Conn}varconnMangermap[string]*Terminal至于为什么定义为指针,是因为定义为指针后,我们可以直接修改元素结构体中对应的变量map无需重新定义元素然后分配值。varconnManagermap[string]*TerminalconnManager=make(map[string]*Terminal)connManager["127.0.0.1:11000"]=&Terminal{}connManager["127.0.0.1:11001"]=&Terminal{}...//这里可以方便的修改对应的phoneNum,修改connManager["127.0.0.1:11001"].phoneNum="13000000000"反而下面的代码修改起来麻烦很多:varconnManagermap[string]TerminalconnManager=make(map[string]Terminal)connManager["127.0.0.1:11000"]=Terminal{}connManager["127.0.0.1:11001"]=Terminal{}...//这里会报错connManager["127.0.0.1:11001"].phoneNum="13000000000"//这里的修改需要定义一个临时变量,类似term的读写模式,ok:=connManager["127.0.0.1:11001"]term.phoneNum="13000000000"connManager["127.0.0.1:11001"]=term上面的代码会报错cannotassigntostructfieldconnManager["127.0.0.1:11001"].phoneNuminmap从上面的对比可以看出这确实是一个定义n变成指针更方便。TCP的长连接模型TCP的长连接我们选择这样一种方式:每个连接分配一个读Goroutine,写数据按需分配。如果熟悉sockets,就知道创建socket服务器的基本步骤:createsocketlistenaccept,accept一般需要Roundrobin调用。golang基本上是相同的过程。一个简单的TCP服务器显示示例:packagemainimport("fmt""net")typeTerminalstruct{authkeystringimeistringiccidstringvinstringtboxverstringphoneNumstringConnnet.Conn}varconnManagermap[string]*TerminalfuncrecvConnMsg(connnet.Conn){addr:=conn.RemoteAddr()varterm*Terminal=&Terminal{Conn:conn,}term.Conn=connconnManager[addr.String()]=termdeferfunc(){delete(connManager,addr.String())conn.Close()}()for{tempbuf:=make([]byte,1024)n,err:=conn.Read(tempbuf)iferr!=nil{return}fmt.Println("rcv:",tempbuf[:n])}}funcTCPServer(addrstring){connManager=make(map[string]*Terminal)listenSock,err:=net.Listen("tcp",addr)iferr!=nil{返回}deferlistenSock.Close()for{newConn,err:=listenSock.Accept()iferr!=nil{continue}gorecvConnMsg(newConn)}}funcmain(){TCPServer(":19903")}下面是测试用的客户端代码:packagemainimport("fmt""net""time")funcmain(){conn,err:=net.Dial("tcp",":19903")如果err!=nil{return}deferconn.Close()varnint=0n,err=conn.Write([]byte("123456"))iferr!=nil{return}fmt.Println("len:",n)for{time.Sleep(time.Second*3)}}测试结果:$./serverrcv:[495051525354]