1、socket.io 简介
Socket.io是一个WebSocket库,包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用。它会自动根据浏览器从WebSocket、AJAX长轮询、Iframe流等等各种方式中选择最佳的方式来实现网络实时应用,非常方便和人性化,而且支持的浏览器最低达IE5.5
socket.io特点
实时分析:将数据推送到客户端,这些客户端会被表示为实时计数器,图表或日志客户。
实时通信和聊天:只需几行代码便可写成一个Socket.IO的”Hello,World”聊天应用。
二进制流传输:从1.0版本开始,Socket.IO支持任何形式的二进制文件传输,例如:图片,视频,音频等。
文档合并:允许多个用户同时编辑一个文档,并且能够看到每个用户做出的修改。
2、golang实现socket.io
引用库:github.com/googollee/go-socket.io@v1.6.0
- 使用http 解决乱问题(使用其他可以忽略)
http.HandleFunc("/socket.io/", func(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
log.Println("origin", origin)
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Credentials", "true")
server.ServeHTTP(w, r)
})
- 此教程采用gin Server端
router := gin.New()
log.SetFlags(log.Lshortfile | log.LstdFlags)
server := socketio.NewServer(nil)
// redis 适配器
ok, err := server.Adapter(&socketio.RedisAdapterOptions{
Addr: "127.0.0.1:6379",
Prefix: "socket.io",
Network: "tcp",
})
fmt.Println("redis:", ok)
if err != nil {
log.Fatal("error:", err)
}
// 连接成功
server.OnConnect("/", func(s socketio.Conn) error {
s.SetContext("")
// 申请一个房间
s.Join("bcast")
fmt.Println("连接成功:", s.ID())
return nil
})
// 接收”bye“事件
server.OnEvent("/", "bye", func(s socketio.Conn, msg string) string {
last := s.Context().(string)
s.Emit("bye", msg)
fmt.Println("============>", last)
//s.Close()
return last
})
server.OnEvent("/chat", "msg", func(s socketio.Conn, msg string) string {
s.SetContext(msg)
fmt.Println("=====chat====>", msg)
return "recv " + msg
})
// 连接错误
server.OnError("/", func(s socketio.Conn, e error) {
log.Println("连接错误:", e)
})
// 关闭连接
server.OnDisconnect("/", func(s socketio.Conn, reason string) {
log.Println("关闭连接:", reason)
})
go server.Serve()
defer server.Close()
router.Use(gin.Recovery(), Cors())
router.GET("/socket.io/*any", gin.WrapH(server))
router.POST("/socket.io/*any", gin.WrapH(server))
router.StaticFS("/public", http.Dir("../asset"))
log.Println("Serving at localhost:8000...")
if err := router.Run(":8000"); err != nil {
log.Fatal("failed run app: ", err)
}
- web端
<html lang="cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>WebSocket</title>
<script type="text/javascript" src="socket.io.js"></script>
</head>
<body>
<h1> socket.io 消息发送测试</h1>
<input id="sendTxt" type="text"/>
<button id="sendBtn">发送</button>
<div id="recv"></div>
<script type="text/javascript">
var socket = io("ws://127.0.0.1:8000/");
var s2 = io("ws://127.0.0.1:8000/chat");
//把接收的数据显示到界面
function showMessage(str,type){
var div = document.createElement('div');
div.innerHTML = str;
if(type == "enter"){
div.style.color = 'blue';
}else if(type == "leave"){
div.style.color = "red"
}
document.body.appendChild(div)
}
// 点击之后发送
document.getElementById("sendBtn").onclick = function(){
var txt = document.getElementById("sendTxt").value;
if(txt){ // 文本不为空发送
socket.emit('bye',txt);
s2.emit("msg","chat-->"+txt)
}
}
// 连接成功
socket.on('connect', function(socket){
showMessage("连接成功",'leave')
// socket.join('RealTimeDataRoom');
});
// 连接失败
socket.on('disconnect', function(socket){
showMessage("连接失败",'leave')
});
socket.on('error', function(socket){
showMessage("连接错误",'leave')
});
socket.on('bye',function(data){
console.log("--------reply--------->",data);
showMessage(data,'enter')
})
</script>
</body>
</html>
- 源码
- 测试截图