• 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) {
    
        },
    });

     

    以上。

  • 相关阅读:
    C++中的空类默认产生哪些类成员函数
    Berkeley Socket API – Creating a TCP/IP client in C
    覆盖父类以及using指令
    strcpy/memcpy/memmove的实现
    [C++对象模型][1]目录与参考
    用setsockopt()来控制recv()与send()的超时
    异常安全的赋值运算符重载函数
    伤不起的指针
    DP01背包
    证明一个数能被3整除,当且仅当它的各位数的和能被3整除
  • 原文地址:https://www.cnblogs.com/chevin/p/8086999.html
Copyright © 2020-2023  润新知