Golang websocket 实现
1.之前使用php的swoole 实现websocket,今天就来用golang基于beego框架实现下,添加二行路由:
beego.Router("/", &controllers.MainController{}) 是网站首页,监测客服端连接情况
beego.Router("/ws", &controllers.MyWebSocketController{}) 供客服端连接
2.先实现服务端代码,直接贴代码如下:
package controllers
import (
"fmt"
"github.com/astaxie/beego"
"github.com/gorilla/websocket"
"h5_api/models"
"log"
"net/http"
)
type MyWebSocketController struct {
beego.Controller
}
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
var (
clients = make(map[*websocket.Conn]bool)
broadcast = make(chan models.Message)
)
func init() {
go handleMessages()
}
func (c *MyWebSocketController) Get() {
conn, err := upgrader.Upgrade(c.Ctx.ResponseWriter, c.Ctx.Request, nil)
if err != nil {
log.Fatal(err)
}
// defer ws.Close()
clients[conn] = true
ip := fmt.Sprintf("id: %v", conn.RemoteAddr())
msg := models.Message{Message: "欢迎进入直播间你的token标记:" + ip}
conn.WriteJSON(msg)
// 连接成功后 给其他客服端发送消息
msgbroadcast := models.Message{Message: "大家号我是新来的我的名字是: " +ip}
broadcast <- msgbroadcast
for {
// 读取客户端的消息
msgType, cmsg, err := conn.ReadMessage()
if err != nil {
return
}
// 把消息打印到标准输出
fmt.Printf("%s sent: %s\n", conn.RemoteAddr(), string(cmsg))
// 把消息写回客户端,完成回音
if err = conn.WriteMessage(msgType, cmsg); err != nil {
return
}
}
}
//广播发送至页面
func handleMessages() {
for {
msg := <-broadcast
fmt.Println("clients len ", len(clients))
for client := range clients {
err := client.WriteJSON(msg)
if err != nil {
log.Printf("client.WriteJSON error: %v", err)
client.Close()
delete(clients, client)
}
}
}
}
简单说明下:
clients 变量是用来存储客服端连接的标示
broadcast 是个 Message 类型的通道,Message类型如下,是当客服端连接成功后,向其他客服端发送广播,
type Message struct {
Message string `json:"message"`
}
在初始化函数内启动个协程
go handleMessages() 发送广播功能
3. 接下来是服务端的主页模版 ,在页面上显示连接客服端的情况 ,这个只是显示下
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>Sample of websocket with golang</title>
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<h1>登录后会在此显示ip</h1>
<ul id="msg-list"></ul>
</body>
</html>
<script>
var div = $('#msg-list')
$(function() {
var ws = new WebSocket('ws://' + window.location.host + '/ws');
var $ul = $('#msg-list');
// 客服端链接触发
ws.onmessage = function(e) {
console.log(event.data)
$('<li>').text(event.data).appendTo(div);
};
});
</script>
4.上述的服务端代码已经全部实现了 ,接下来实现客服端代码,客服端的代码就很简单了,代码如下
<head>
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<body>
websocket 客服端
<ul id="msg-list"></ul>
</body>
</head>
<script>
var div = $('#msg-list')
var wsServer = 'ws://127.0.0.1:8080/ws';
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
websocket.send("websocket i am client" + Math.floor(Math.random() * 10000))
console.log("Connected to WebSocket server.");
};
websocket.onclose = function (evt) {
console.log("Disconnected");
};
// setInterval(function () {
// websocket.send("websocket i am client" + Math.floor(Math.random() * 10000))
// }, 5000);
websocket.onmessage = function (evt) {
$('<li>').text(evt.data).appendTo(div);
};
websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
</script>
这里说明下
我们只服务端开启的端口是8080;所以这里的webserver 是 ws://127.0.0.1:8080/ws,前面的ws就是websocket服务的协议了,后面的ws是服务端的访问路径,这个可以随便命名。
onopen 方法是连接上服务端是触发,这里就简答向客服端发送一段随机的字符串了
onmessage 方法是接受服务端推送过来的消息
至此 基于golang的websocket 已全部实现,感兴趣的小伙伴可以尝试下,有疑问可以在讨论区交流哦!