分享
  1. 首页
  2. 文章

Golang websocket

mickelfeng · · 7703 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

环境:Win10 + Go1.9.2

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

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

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

3使用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\n";
 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.

1客户端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\n";
 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.")
}

2如果客户端不使用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) {
 },
});

有疑问加站长微信联系(非本文作者)

本文来自:开源中国博客

感谢作者:mickelfeng

查看原文:Golang websocket

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
7703 次点击 ∙ 1 赞
1 回复 | 直到 2019年01月09日 18:58:03
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏