网站首页linux

golang生成websocket应用,并使用nginx反向代理开启wss连接

发布时间:2024-08-23 14:51:23编辑:阅读(499)

    1. 使用go生成websocket应用

    package main
    
    import (
    	"encoding/json"
    	"log"
    	"net/http"
    	"sync"
    
    	"github.com/gorilla/websocket"
    )
    
    var upgrader = websocket.Upgrader{
    	ReadBufferSize:  1024,
    	WriteBufferSize: 1024,
    	CheckOrigin: func(r *http.Request) bool {
    		return true
    	},
    }
    
    type Client struct {
    	conn *websocket.Conn
    	code string
    	mode string
    }
    
    type MsgData struct {
    	Code    string `json:"code"`
    	Mode    string `json:"mode"`
    	Payload string `json:"payload"`
    }
    
    var clients = make(map[*Client]bool)
    var mutex = &sync.Mutex{}
    
    func handler(w http.ResponseWriter, r *http.Request) {
    	conn, err := upgrader.Upgrade(w, r, nil)
    	if err != nil {
    		log.Println(err)
    		return
    	}
    
    	client := &Client{conn: conn, code: r.URL.Query().Get("code"), mode: r.URL.Query().Get("mode")}
    	mutex.Lock()
    	clients[client] = true
    	mutex.Unlock()
    
    	go func() {
    		for {
    			messageType, p, err := conn.ReadMessage()
    			if err != nil {
    				log.Println("读时连接已关闭")
    				clients[client] = false
    				client.conn.Close()
    				mutex.Lock()
    				delete(clients, client)
    				mutex.Unlock()
    				return
    			}
    			log.Println(string(p))
    
    			// 处理接收到的数据
    			var data MsgData
    			if err := json.Unmarshal(p, &data); err == nil {
    				log.Println(data.Code, data.Mode)
    			} else {
    				log.Println(err)
    			}
    			for client := range clients {
    				if client.code == data.Code && client.mode != data.Mode {
    					if err := client.conn.WriteMessage(messageType, p); err != nil {
    						log.Println("写时连接已关闭")
    						clients[client] = false
    						client.conn.Close()
    						mutex.Lock()
    						delete(clients, client)
    						mutex.Unlock()
    						return
    					}
    				}
    			}
    
    			log.Println(clients)
    		}
    	}()
    
    	log.Printf(" %s 客户端 %s 已连接", client.mode, client.code)
    }
    
    func main() {
    	http.HandleFunc("/ws", handler)
    	log.Fatal(http.ListenAndServe(":9504", nil))
    }
    

    编译生成应用程序

    linux下使用:

    set GOARCH=amd64
    set GOOS=linux
    set CGO_ENABLED=0
    go build -o websocket

    windows下使用:

    set GOARCH=amd64
    set GOOS=windows
    set CGO_ENABLED=0
    go build -o websocket.exe

    2. 将应用程序上传至服务器,并启动。

    3. 在nginx里配置反向代理

    location ~ /wss {
    	proxy_set_header  Host $host;
    	proxy_set_header  X-Real-IP  $remote_addr;
    	proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;		
    	proxy_set_header  REMOTE-HOST $remote_addr;	
    	proxy_set_header  Upgrade $http_upgrade;
    	proxy_set_header  Connection "upgrade";
    	proxy_http_version 1.1;
    	proxy_pass        http://127.0.0.1:9001;
    }

    4. 使用js的websocket客户端连接访问

    var ws = new WebSocket("wss://yourdomain/wss");    
    ws.onopen = function() {  
        console.log("Connection open ...");  
    };    
    ws.onmessage = function(evt) {   
        console.log( "Received Message: " + evt.data);  
    };    
    ws.onclose = function() {   
        console.log("Connection closed.");  
    };
    ws.send('message');
    ws.close();  


评论