Using Golang to implement chat communication

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Implementing logic

1, Golang version 1.3

2, the realization principle:

1, the main process to establish a TCP monitoring service, and initialize a variable Talkchan: = Make (Map[int]chan string)

2, when the main process accept connection request, use go to start a process A to maintain the connection with the client, bring Taokchan into the co-thread

3, and the client to establish a connection to the process a, send a message to the client, so that it sends its own user information.

4. After receiving the user information sent by the client, we establish a pipeline for this user Talkchan[uid] = make (Chan string)

5, co-process A and then start a co-A1 to read the message sent by the client, and to determine who is sent to the message, and then put the message to the corresponding Chan.

6, the co-process A and then start a A2 to read this user's corresponding pipeline, if there is information, then take out to send to the client.


Implementation code

Service-side test code: SERVER.GO

Package Mainimport ("FMT" "Log" "Net" "StrConv") func handleconnection (conn net. Conn, Talkchan Map[int]chan string) {//fmt. Printf ("%p\n", Talkchan)//used to check if the pointer is passed/* Defines the current user's Uid*/var curuid intvar err error/* define close channel */var closed = make (chan bool) d Efer func () {fmt. Println ("defer do:conn closed") Conn. Close () fmt. Printf ("delete userid [%v] from Talkchan", Curuid) Delete (Talkchan, Curuid)} ()/** * Prompts the user to set their own UID, if not set, does not execute */for {//prompt The client sets the user id_, err = conn. Write ([]byte ("Set user UID")) if err! = Nil {return}data: = make ([]byte, 1024x768) c, err: = conn. Read (data) if err! = Nil {//closed <-true//this will block | Back the For loop that takes closed, not executed to. Return}suid: = string (Data[0:c])//turn to the INT type UID, _: = StrConv. Atoi (SUid) if UID < 1 {continue}curuid = Uidtalkchan[uid] = make (Chan string)//fmt. PRINTLN (Conn, "has set UID", UID, "can Talk") _, Err = conn. Write ([]byte ("has set UID" +suid+ "can Talk")) if err! = Nil {return}break}fmt. Println ("Err 3")//Current all connections to FMT. PRINTLN (Talkchan)//Read the data sent by the client to go func () {for {//Read client data sent overKe ([]byte, 1024x768) c, err: = conn. Read (data) if err! = Nil {fmt. Println ("Have no client write", err) closed <-true//Can be used here |  Because it was handled with a new thread of go. | Even if Chan blocks, the back will execute to read closed this chan}clientstring: = String (Data[0:c])//Send the client data, write to the corresponding Chan if Curuid = = 3 {talkchan[4] <-clientstring} else {talkchan[3] <-clientstring}}} ()/* Read the data from Chan to the client and write it to the client */go func () {for {talkstring}: = <-talkchan[curuid]_, err = conn. Write ([]byte (talkstring)) if err! = Nil {closed <-true}}} ()/* Check whether the connection is closed if it is closed then eject the thread to execute the defer statement */for {if <-closed {return}}} Func Main () {/** establishes a listener link */ln, err: = Net. Listen ("TCP", "127.0.0.1:6010") if err! = Nil {panic (err)}//Create a pipeline//talkchan: = Map[f]talkchan: = Make (Map[int]chan String) fmt. Printf ("%p\n", Talkchan)/* Listens if there is a connection request coming from the client */for {FMT. PRINTLN ("Wait Connect ...") conn, err: = ln. Accept () if err! = Nil {log. Fatal ("Get Client Connection Error:", err)}go handleconnection (conn, Talkchan)}}

Client Test code: Client.go

Package Mainimport ("FMT" "Math/rand" "NET") Func main () {conn, err: = Net. Dial ("TCP", "127.0.0.1:6010") if err! = Nil {panic (err)}fmt. fprintf (conn, "Hello server\n") defer Conn. Close () go writefromserver (conn) for {var talkcontent stringfmt. SCANLN (&talkcontent) If Len (talkcontent) > 0 {_, err = conn. Write ([]byte (talkcontent)) if err! = Nil {fmt. Println ("Write to Server Error") Return}}}}func Connect () {conn, err: = Net. Dial ("TCP", "127.0.0.1:6010") if err! = Nil {panic (err)}fmt. fprintf (conn, "Hello server\n") defer Conn. Close () go writefromserver (conn) for {var talkcontent stringfmt. SCANLN (&talkcontent) If Len (talkcontent) > 0 {_, err = conn. Write ([]byte (talkcontent)) if err! = Nil {fmt. Println ("Write to Server Error") Return}}}}func Writefromserver (conn net. Conn) {defer Conn. Close () for {data: = make ([]byte, 1024x768) c, err: = conn. Read (data) if err! = Nil {fmt. PRINTLN ("Rand", Rand.) INTN (+), "have no server write", err) return}fmt. Println (String (data[0:c]) + "\ n")}}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.