1. 项目地址:
    # 服务端
    https://github.com/googollee/go-socket.io
    # 客户端(go)
    https://github.com/zhouhui8915/go-socket.io-client
    # 客户端(javascript)
    https://cdnjs.com/libraries/socket.io
  2. socket.io 相关概念:
     1. 命名空间:相当于 url 下的不同路径;
     2. 广播
     3. 房间
     4. 自定义事件
  3. 示例代码:
    1. go 服务器:
      package main
      import (
      "fmt"
      "log"
      "net/http"
      "github.com/googollee/go-socket.io"
      "net/url"
      )
      func main() {
      server, err := socketio.NewServer(nil)
      if err != nil {
       log.Fatal(err)
      }
      ///////////////////////////////////////////////////////////
      // 命名空间:/chat 下
      server.OnConnect("/chat", func(s socketio.Conn) error {
       s.SetContext("消息传递")
       fmt.Println("connected:", s.ID())
       // 获取查询参数
       params,_ := url.ParseQuery(s.URL().RawQuery)
       username := params.Get("username")
       password := params.Get("password")
       fmt.Println(username,password)
       s.Join("room")  // 加入房间
       return nil
      })
      server.OnEvent("/chat", "msg:1", func(s socketio.Conn, msg string) {
       fmt.Println(msg,s.Context())
       s.Emit("msg:1", "world - 1")  // 服务端发送消息:只给当前连接的用户发送消息
       s.Close()  // 服务端主动断开与当前用户的连接
      })
      server.OnEvent("/chat", "msg:2", func(s socketio.Conn, msg string) {
       fmt.Println(msg)
       server.BroadcastToRoom("/chat", "room", "msg:2", "world - 2")  // 服务端发送消息:给所有加入房间的用户发送消息
      })
      // 失去连接事件,可以做一些登出操作
      server.OnDisconnect("/", func(s socketio.Conn, reason string) {
       fmt.Println("closed", reason)
      })
      ///////////////////////////////////////////////////////////
      // 错误处理事件,可忽略
      server.OnError("/", func(s socketio.Conn, e error) {
       fmt.Println("meet error:", e)
      })
      go server.Serve()
      defer server.Close()
      // 登录功能:localhost:8000/login
      http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
       w.Header().Set("Access-Control-Allow-Origin", "*")             // 允许访问所有域
       w.Header().Add("Access-Control-Allow-Headers", "Content-Type")  // header的类型
       w.Header().Set("content-type", "application/json")             // 返回数据格式是json
       fmt.Println("login")  // 输出到控制台
       fmt.Fprintf(w, "login")  // 输出到客户端
      })
      // 文件上传功能:localhost:8000/upload
      http.HandleFunc("/upload", func(w http.ResponseWriter, r *http.Request) {
       fmt.Println("upload")  // 输出到控制台
       fmt.Fprintf(w, "upload")  // 输出到客户端
      })
      // 静态文件服务器:localhost:8000/test.txt  -->  ./file/test.txt
      http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir("./file"))))
      // socket.io 核心功能
      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)
      })
      log.Println("请打开网址: http://localhost:8080 进行访问...")
      log.Fatal(http.ListenAndServe(":8000", nil))
      }
    2. go 客户端(不支持命名空间〜〜):
      package main
      import (
      "fmt"
      "github.com/zhouhui8915/go-socket.io-client"
      "log"
      "time"
      )
      func main() {
      ticker := time.NewTicker(time.Second * 10)
      opts := &socketio_client.Options{
       Transport: "websocket",
       Query:     make(map[string]string),
      }
      uri := "http://localhost:8000"
      client, err := socketio_client.NewClient(uri, opts)
      if err != nil {
       log.Printf("NewClient error:%v\n", err)
       return
      }
      for{
       ////////////////////////////////////////////////
       // 发送消息
       client.Emit("msg:1","hello - 1")
       client.Emit("msg:2","hello - 2")
       // 接收消息
       client.On("msg:1", func(msg string) {
           fmt.Println(msg)
       })
       client.On("msg:2", func(msg string) {
           fmt.Println(msg)
       })
       ////////////////////////////////////////////////
       // 错误处理和连接失败消息,可忽略
       client.On("error", func() {
           log.Printf("on error\n")
       })
       client.On("disconnection", func() {
           log.Printf("on disconnect\n")
       })
       <- ticker.C
      }
      }
    3. js 客户端(官网说只支持版本 1.4.x 以下的…):
      <!doctype html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <meta name="viewport"
         content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <script src="jquery.min.js"></script>
      <script src="socket.io.js"></script>
      </head>
      <body>
      <script>
      // 使用 /chat 命名空间
      var socket = io('http://localhost:8000/chat',{
       query: {
           username: 'username',
           password: 'password',
       }
      });
      // 发送消息
      socket.emit('msg:1', "hello - 1")
      socket.emit('msg:2', "hello - 2")
      // 接收消息
      socket.on('msg:1',function(msg) {
       alert(msg)
      });
      socket.on('msg:2',function(msg) {
       alert(msg)
      });
      </script>
      </body>
      </html>
文档更新时间: 2020-10-23 09:26   作者:lee