创建WebSocket服务器

服务端

package main

import (
   "fmt"
   "github.com/gorilla/websocket"
   "net/http"
   "time"
)

func serveClient(conn *websocket.Conn) {
   client := conn.RemoteAddr() // 客户端标识,格式为“IP地址:端口号”
   fmt.Printf("********** 客户端『%+v』与服务器连接成功 **********\n", client)

   // 关闭与客户端的连接
   defer func(conn *websocket.Conn) {
      _ = conn.Close()
   }(conn)

   // 开启死循环监听客户端向服务器发送消息
   for {
      messageType, messageByte, err1 := conn.ReadMessage()
      if err1 != nil {
         if messageType == -1 {
            fmt.Printf("********** 客户端『%+v』与服务器断开连接 **********\n", client)
            break
         } else {
            panic("读取客户端发送过来的消息失败,原因:" + err1.Error())
         }
      } else {
         messageStr := string(messageByte)
         fmt.Printf("收到客户端『%+v』发送过来的消息(消息类型=%+v):%+v \n", client, messageType, messageStr)

         // 处理客户端发送过来的特定消息
         if messageStr == "世界上最好の语言是什么?" {
            err2 := conn.WriteMessage(websocket.TextMessage, []byte("PHP是世界上最好の语言")) // 向客户端返回消息
            if err2 != nil {
               panic("服务器向客户端发送消息失败,原因:" + err2.Error())
            }

            // _ = conn.Close() // 服务器主动与客户端断开连接
         }
      }
   }
}

func main() {
   upgrader := websocket.Upgrader{
      ReadBufferSize:   1024,
      WriteBufferSize:  1024,
      HandshakeTimeout: 5 * time.Second,
      CheckOrigin: func(r *http.Request) bool {
         return true // 解决跨域问题
      },
   }

   http.HandleFunc("/websocket", func(writer http.ResponseWriter, request *http.Request) {
      conn, err := upgrader.Upgrade(writer, request, nil) // HTTP服务器连接升级为WebSocket协议
      if err != nil {
         panic("连接WebSocket服务器失败,原因:" + err.Error())
      } else {
         // 启动一个协程为该客户端服务
         go serveClient(conn)
      }
   })

   _ = http.ListenAndServe(":9527", nil)

   // 上面的WebSocket服务使用ws协议,如果要使用wss协议(使用SSL证书)可换成ListenAndServeTLS()方法
   // 需要注意的是SSL证书和域名是绑定的,所以客户端在创建WebSocket对象时参数URL必须是和SSL证书对应的域名,不能使用IP地址
   // _ = http.ListenAndServeTLS(":9527", "*.pem文件路径", "*.key文件路径", nil)
}

//========== 输出过程·开始 ==========//
// ********** 客户端『192.168.1.2:58809』与服务器连接成功 **********
// 收到客户端『192.168.1.2:58809』发送过来的消息(消息类型=1):孩儿立志出乡关
// 收到客户端『192.168.1.2:58809』发送过来的消息(消息类型=1):学不成名誓不还
// 收到客户端『192.168.1.2:58809』发送过来的消息(消息类型=1):埋骨何须桑梓地
// 收到客户端『192.168.1.2:58809』发送过来的消息(消息类型=1):人生无处不青山
// 收到客户端『192.168.1.2:58809』发送过来的消息(消息类型=1):世界上最好の语言是什么?
// ********** 客户端『192.168.1.2:58809』与服务器断开连接 **********
//========== 输出过程·结束 ==========//



客户端

var ws = new WebSocket('ws://192.168.1.1:9527/websocket');

// 打开WebSocket后的回调函数
ws.onopen = function () {
    console.log('与服务器连接成功'); // 与服务器连接成功

    setTimeout(function () {
        ws.send('孩儿立志出乡关'); // 向服务器发送消息
    }, 2500);

    setTimeout(function () {
        ws.send('学不成名誓不还'); // 向服务器发送消息
    }, 5000);

    setTimeout(function () {
        ws.send('埋骨何须桑梓地'); // 向服务器发送消息
    }, 7500);

    setTimeout(function () {
        ws.send('人生无处不青山'); // 向服务器发送消息
    }, 10000);

    setTimeout(function () {
        ws.send('世界上最好の语言是什么?'); // 向服务器发送消息
    }, 12500);

    setTimeout(function () {
        ws.close(); // 主动断开与服务器的连接
    }, 15000);
};

// 接收到服务器发过来消息后的回调函数
ws.onmessage = function (e) {
    console.log(e.data); // PHP是世界上最好の语言
};

// 与服务器断开连接后的回调函数
ws.onclose = function (e) {
    console.log('与服务器断开连接');
};



设置开机自动启动WebSocket服务器
[root@localhost ~]# vim /etc/systemd/system/websocket.service
[Unit]
Description=这里可填写WebSocket服务器的描述文字
After=network.target
 
[Service]
Type=forking
ExecStart=/server/websocket.exe
 
[Install]
WantedBy=multi-user.target
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl enable websocket.service # 设置开机自动启动WebSocket服务器
[root@localhost ~]# shutdown -r now # 重启系统,测试是否开机自动启动WebSocket服务器
说明:/server/websocket.exe是Go编译服务端代码生成的可执行文件。

Copyright © 2024 码农人生. All Rights Reserved