zoukankan      html  css  js  c++  java
  • Golang websocket

    环境:Win10 + Go1.9.2

    1.先下载并引用golang的websocket库

    ①golang的官方库都在https://github.com/golang下,而websocket库在/net下。

    ②如果没有安装Git,需要先安装Git。

    ③使用go get -u github.com/golang/net/websocket下载代码,将安装在环境变量GOPATH配置的路径中。

    代码中使用路径为 "golang.org/x/net/websocket",在对应路径下没有代码的话则引用出错,可将对应代码放在GOPAHT/golang.org/x/net下。

     

    2.服务端Go代码

    package main
    
    import (
        "fmt"
        "golang.org/x/net/websocket"
        "net/http"
        "os"
        "time"
    )
    
    //错误处理函数
    func checkErr(err error, extra string) bool {
        if err != nil {
            formatStr := " Err : %s
    ";
            if extra != "" {
                formatStr = extra + formatStr;
            }
    
            fmt.Fprintf(os.Stderr, formatStr, err.Error());
            return true;
        }
    
        return false;
    }
    
    func svrConnHandler(conn *websocket.Conn) {
        request := make([]byte, 128);
        defer conn.Close();
        for {
            readLen, err := conn.Read(request)
            if checkErr(err, "Read") {
                break;
            }
    
            //socket被关闭了
            if readLen == 0 {
                fmt.Println("Client connection close!");
                break;
            } else {
                //输出接收到的信息
                fmt.Println(string(request[:readLen]))
    
                time.Sleep(time.Second);
                //发送
                conn.Write([]byte("World !"));
            }
    
            request = make([]byte, 128);
        }
    }
    
    func main() {
        http.Handle("/echo", websocket.Handler(svrConnHandler));
        err := http.ListenAndServe(":6666", nil);
        checkErr(err, "ListenAndServe");
        fmt.Println("Func finish.");
    }

     PS:《Golang socket》中使用了go coroutine来处理connection的消息阻塞接收,websocket不需要进行这样的处理,否则将报use of closed network connection的错误!

     3.

    ①客户端Go代码

    package main
    
    import (
        "fmt"
        "golang.org/x/net/websocket"
        "os"
        "sync"
    )
    
    var gLocker sync.Mutex;    //全局锁
    var gCondition *sync.Cond; //全局条件变量
    
    var origin = "http://127.0.0.1:6666/"
    var url = "ws://127.0.0.1:6666/echo"
    
    //错误处理函数
    func checkErr(err error, extra string) bool {
        if err != nil {
            formatStr := " Err : %s
    ";
            if extra != "" {
                formatStr = extra + formatStr;
            }
    
            fmt.Fprintf(os.Stderr, formatStr, err.Error());
            return true;
        }
    
        return false;
    }
    
    //连接处理函数
    func clientConnHandler(conn *websocket.Conn) {
        gLocker.Lock();
        defer gLocker.Unlock();
        defer conn.Close();
        request := make([]byte, 128);
        for {
            readLen, err := conn.Read(request)
            if checkErr(err, "Read") {
                gCondition.Signal();
                break;
            }
    
            //socket被关闭了
            if readLen == 0 {
                fmt.Println("Server connection close!");
    
                //条件变量同步通知
                gCondition.Signal();
                break;
            } else {
                //输出接收到的信息
                fmt.Println(string(request[:readLen]))
    
                //发送
                conn.Write([]byte("Hello !"));
            }
    
            request = make([]byte, 128);
        }
    }
    
    func main() {
        conn, err := websocket.Dial(url, "", origin);
        if checkErr(err, "Dial") {
            return;
        }
    
        gLocker.Lock();
        gCondition = sync.NewCond(&gLocker);
        _, err = conn.Write([]byte("Hello !"));
        go clientConnHandler(conn);
    
        //主线程阻塞,等待Singal结束
        for {
            //条件变量同步等待
            gCondition.Wait();
            break;
        }
        gLocker.Unlock();
        fmt.Println("Client finish.")
    }

     

    ②如果客户端不使用Go代码,可以使用Cocos Creator的js代码

    cc.Class({
        extends: cc.Component,
    
        properties: {
    
        },
    
        ctor: function () {
            this.ws = null;
        },
    
        onLoad: function () {
            var self = this;
    
            this.ws = new WebSocket("ws://127.0.0.1:6666/echo");
            this.ws.onopen = function (event) {
    
                console.log("Send Text WS was opened.");
    
                if (self.ws.readyState === WebSocket.OPEN) {
                    self.ws.send("Hello !");
                }
                else{
                    console.log("WebSocket instance wasn't ready...");
                }
            };
    
            this.ws.onmessage = function (event) {
                console.log("response text msg: " + event.data);
                self.ws.send("Hello !");
            };
    
            this.ws.onerror = function (event) {
                console.log("Send Text fired an error");
            };
    
            this.ws.onclose = function (event) {
                console.log("WebSocket instance closed.");
            };
    
        },
    
        // called every frame
        update: function (dt) {
    
        },
    });

     

    以上。

  • 相关阅读:
    创建数据库的那些事
    同步、异步、阻塞、非阻塞我的理解
    Openfire MultiUserChat 多用户聊天 消息发送
    JAVA 随机字符串
    OF 同步异步问题的改进
    Openfire S2S 监听与消息处理
    MySQL FEDERATED 存储引擎
    一个S2S通信中的同步、异步问题的解决
    Openfire Monitoring/jinglenodes plugin error
    Java Cache System JCS(一) 使用方法
  • 原文地址:https://www.cnblogs.com/chevin/p/8086999.html
Copyright © 2011-2022 走看看