依赖包

github.com/gin-gonic/gingithub.com/gorilla/websocket

代码

创立ws/ws.go

package wsimport (    "encoding/json"    "github.com/gin-gonic/gin"    "github.com/gorilla/websocket"    "log"    "net/http")// ClientManager is a websocket managertype ClientManager struct {    Clients    map[string]*Client    Broadcast  chan []byte    Register   chan *Client    Unregister chan *Client}// Client is a websocket clienttype Client struct {    ID     string    Socket *websocket.Conn    Send   chan []byte}// Message is return msgtype Message struct {    Sender    string `json:"sender,omitempty"`    Recipient string `json:"recipient,omitempty"`    Content   string `json:"content,omitempty"`}// Manager define a ws server managervar Manager = ClientManager{    Broadcast:  make(chan []byte),    Register:   make(chan *Client),    Unregister: make(chan *Client),    Clients:    make(map[string]*Client),}// Start is  我的项目运行前, 协程开启start -> go Manager.Start()func (manager *ClientManager) Start() {    for {        log.Println("<---管道通信--->")        select {        case conn := <-Manager.Register:            log.Printf("新用户退出:%v", conn.ID)            Manager.Clients[conn.ID] = conn            jsonMessage, _ := json.Marshal(&Message{Content: "Successful connection to socket service"})            conn.Send <- jsonMessage        case conn := <-Manager.Unregister:            log.Printf("用户来到:%v", conn.ID)            if _, ok := Manager.Clients[conn.ID]; ok {                jsonMessage, _ := json.Marshal(&Message{Content: "A socket has disconnected"})                conn.Send <- jsonMessage                close(conn.Send)                delete(Manager.Clients, conn.ID)            }        case message := <-Manager.Broadcast:            MessageStruct :=Message{}            json.Unmarshal(message, &MessageStruct)            for id, conn := range Manager.Clients {                if id!=creatId(MessageStruct.Recipient,MessageStruct.Sender){                    continue                }                select {                case conn.Send <- message:                default:                    close(conn.Send)                    delete(Manager.Clients, conn.ID)                }            }        }    }}func creatId(uid,touid string) string {    return uid+"_"+touid}func (c *Client) Read() {    defer func() {        Manager.Unregister <- c        c.Socket.Close()    }()    for {        c.Socket.PongHandler()        _, message, err := c.Socket.ReadMessage()        if err != nil {            Manager.Unregister <- c            c.Socket.Close()            break        }        log.Printf("读取到客户端的信息:%s", string(message))        Manager.Broadcast <- message    }}func (c *Client) Write() {    defer func() {        c.Socket.Close()    }()    for {        select {        case message, ok := <-c.Send:            if !ok {                c.Socket.WriteMessage(websocket.CloseMessage, []byte{})                return            }            log.Printf("发送到到客户端的信息:%s", string(message))            c.Socket.WriteMessage(websocket.TextMessage, message)        }    }}//TestHandler socket 连贯 中间件 作用:降级协定,用户验证,自定义信息等func WsHandler(c *gin.Context) {    uid := c.Query("uid")    touid := c.Query("to_uid")    conn, err := (&websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }}).Upgrade(c.Writer, c.Request, nil)    if err != nil {        http.NotFound(c.Writer, c.Request)        return    }    //能够增加用户信息验证    client := &Client{        ID:    creatId(uid,touid),        Socket: conn,        Send:   make(chan []byte),    }    Manager.Register <- client    go client.Read()    go client.Write()}

创立main.go

package mainimport (    "github.com/gin-gonic/gin"    "im/ws")//serverfunc main() {    gin.SetMode(gin.ReleaseMode) //线上环境    go ws.Manager.Start()    r := gin.Default()    r.GET("/ws",ws.WsHandler)    r.GET("/pong", func(c *gin.Context) {        c.JSON(200, gin.H{            "message": "pong",        })    })    r.Run(":8282") // listen and serve on 0.0.0.0:8080}

运行服务端

go  run  mian.go

创立client.html

<html><head>    <title>Golang Chat</title><script src="http://libs.baidu.com/jquery/1.4.2/jquery.min.js"></script><meta charset="UTF-8" />    <script type="text/javascript">            $(function() {            function getUrlParam(name)            {                var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); //结构一个含有指标参数的正则表达式对象                var r = window.location.search.substr(1).match(reg);  //匹配指标参数                if (r!=null) return unescape(r[2]); return null; //返回参数值            }            var conn;            var msg = $("#msg");            var log = $("#log");            uid=getUrlParam("uid");            to_uid=getUrlParam("to_uid");            function appendLog(msg) {                var d = log[0]                var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight;                msg.appendTo(log)                if (doScroll) {                    d.scrollTop = d.scrollHeight - d.clientHeight;                }            }            $("#form").submit(function() {                if (!conn) {                    return false;                }                if (!msg.val()) {                    return false;                }                var json = {"sender":uid,"recipient":to_uid,"content":msg.val()}; //创建对象;                var jsonStr = JSON.stringify(json);       //转为JSON字符串                conn.send(jsonStr);                msg.val("");                return false            });            if (window["WebSocket"]) {                conn = new WebSocket("ws://localhost:8282/ws?uid="+uid+"&to_uid="+to_uid);                conn.onclose = function(evt) {                    appendLog($("<div><b>Connection Closed.</b></div>"))                }                conn.onmessage = function(evt) {                                        appendLog($("<div/>").text(evt.data))                }            } else {                appendLog($("<div><b>WebSockets Not Support.</b></div>"))            }        });    </script>    <style type="text/css">        html {            overflow: hidden;        }        body {            overflow: hidden;            padding: 0;            margin: 0;            width: 100%;            height: 100%;            background: gray;        }        #log {            background: white;            margin: 0;            padding: 0.5em 0.5em 0.5em 0.5em;            position: absolute;            top: 0.5em;            left: 0.5em;            right: 0.5em;            bottom: 3em;            overflow: auto;        }        #form {            padding: 0 0.5em 0 0.5em;            margin: 0;            position: absolute;            bottom: 1em;            left: 0px;            width: 100%;            overflow: hidden;        }    </style></head><body><div id="log"></div><form id="form">    <input type="submit" value="发送" />    <input type="text" id="msg" size="64"/></form></body></html>

本人搭建nginx或apache等web服务,别离在两个窗口运行

http://localhost/client.html?...

http://localhost/client.html?...

这样就能够聊天了

links

  • 目录
  • 上一节:
  • 下一节: