Usually the chat room architecture is divided into server-side and client:
Server-side:
Accept the connection request from the client and establish the connection;
All client connections are placed into the connection pool for broadcast messages;
Client:
Connect to the server;
Send a message to the server;
Receiving a broadcast message from the server;
Precautions:
A client disconnects from the connection pool after disconnection and no longer receives the broadcast message;
A client can not affect the server side or other client connection after disconnecting;
The detailed code is as follows, and the document looks at the comments, no longer elaborate:
Server:
Server.go
Package Mainimport ("NET" "Log" "FMT") func main () {port: = "9090" Start (port)}//Start server func start (Port str ing) {host: = ":" + Port//Get TCP address tcpaddr, err: = Net. RESOLVETCPADDR ("TCP4", host) if err! = Nil {log. PRINTF ("Resolve TCP addr failed:%v\n", err) return}//Listener listener, ERR: = Net. LISTENTCP ("TCP", TCPADDR) if err! = Nil {log. PRINTF ("Listen TCP port failed:%v\n", err) return}//Establish connection pool for broadcast message Conns: = Make (map[string]net. Conn)//Message Channel Messagechan: = Make (Chan string, 10)//Broadcast message Go broadmessages (&conns, Messagechan)//Start for {fmt. Printf ("Listening port%s ... \ n", port) conn, err: = Listener. ACCEPTTCP () if err! = Nil {log. Printf ("Accept failed:%v\n", err) continue}//throws each client connection into the connection pool conns[conn. Remoteaddr (). String ()] = conn FMT. PRINTLN (Conns)//Processing messages Go Handler (conn, &conns, Messagechan) }}//broadcast func broadmessages (Conns *map[string]net) to all connected folks. Conn, Messages Chan string) {for {//continuously reads messages from the Channel msg: = <-messages fmt. PRINTLN (msg)//Send message to all folks for key, conn: = Range *conns {fmt. PRINTLN ("Connection is connected from", key) _, ERR: = conn. Write ([]byte (msg)) if err! = Nil {log. Printf ("Broad message to%s failed:%v\n", key, Err) Delete (*conns, key)}}}}//process customer End sends a message to the server and throws it into the channel func Handler (Conn net. Conn, Conns *map[string]net. Conn, Messages Chan string) {fmt. PRINTLN ("Connect from client", Conn. Remoteaddr (). String ()) BUF: = Make ([]byte, 1024x768) for {length, err: = conn. Read (BUF) if err! = Nil {log. Printf ("Read client message failed:%v\n", err) Delete (*conns, Conn. Remoteaddr (). String ()) Conn. Close () Break}//writes the received message to the Channel recvstr: = string (Buf[0:length]) Messages <-Recvstr}}
Client:
Client.go
Package Mainimport ("NET" "Log" "FMT" "OS") Func main () {Start (OS. ARGS[1])}func Start (Tcpaddrstr string) {tcpaddr, err: = Net. RESOLVETCPADDR ("TCP4", TCPADDRSTR) if err! = Nil {log. Printf ("Resolve TCP addr failed:%v\n", err) return}//dial to Server conn, err: = Net. DIALTCP ("TCP", nil, tcpaddr) if err! = Nil {log. Printf ("Dial to Server failed:%v\n", err) return}//Send a message to the server go SENDMSG (conn)//Receive broadcast messages from the server side BUF : = Make ([]byte, 1024x768) for {length, err: = conn. Read (BUF) if err! = Nil {log. Printf ("Recv server msg failed:%v\n", ERR) Conn. Close () OS. Exit (0) break} fmt. Println (String (Buf[0:length]))}}//sends a message to the server, func sendmsg (conn net. Conn) {username: = Conn. Localaddr (). String () for {var input string//receives input message and places it into FMT in input variable. SCANLN (&input) if input = = "/q" | | input = = "/quit" {fmt. Println("Byebye ...") Conn. Close () OS. Exit (0)}//Handle only messages with content if Len (input) > 0 {msg: = Username + "SAY:" + input _, ERR: = conn. Write ([]byte (msg)) if err! = NIL {conn. Close () Break}}}}
Test method:
compiling server.go and Client.go;
Open the terminal, start the server, the default is to listen to 9090 port;
Open multiple terminal, start client,client Start command: Client server ip:9090;
Enter the characters in the client and return to the terminal, you can see the other terminals will receive messages;