前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go语言实现的WebSocket

Go语言实现的WebSocket

作者头像
李海彬
发布2018-09-29 12:24:56
3.7K0
发布2018-09-29 12:24:56
举报
文章被收录于专栏:Golang语言社区

作者:豌豆射手_BiuBiu 链接:https://www.jianshu.com/p/a5b187f7e669 來源:简书

  • 最终的效果如下

Web端上传的信息

Web端得到的打印的信息

服务端的代码的实现

服务端的信息

  • WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范。WebSocket是HTML5的重要特性,它实现了基于浏览器的远程socket,它使浏览器和服务器可以进行全双工通信,许多浏览器Firefox、Google Chrome和Safari都已对此做了支持
  • WebSocket出现之前,为了实现即时通信,采用的技术都是“轮询”,即在特定的时间间隔内,由浏览器对服务器发出HTTP Request,服务器在收到请求后,返回最新的数据给浏览器刷新,“轮询”使得浏览器需要对服务器不断发出请求,这样会占用大量带宽。
  • 很多的游戏的服务都是采用的是Socket,因为HTTP协议相对而言比较耗费性能, 随着HTML5的发展,WebSocket也逐渐发展成为很多页游公司接下来开发的一些手段。
  • 安卓推送的原理: C2DM 推送 (Google) C2DM 推送简介 : 全称 Cloudto Device Messaging, Google 提供的 推送解决方案;
    • 运行方式 : 提供一个轻量级机制, 允许服务器通知应用程序, 主动与客户端进行数据交互, 处理消息排队, 并向运行于目标设备的应用程序分发消息;
    • 优点 : Google 提供的原生框架, 无需在应用中添加第三方代码 和 部署服务器端;
    • 缺点 : 1.该推送依赖 Google 服务器, 需要绑定 Google 帐号, 目前在中国 Google 被屏蔽, 无法使用; 2. 许多手机厂商去掉了软件中的该模块;
  • 极光推送的原理:因为IP v4 的 IP 量有限,运营商分配给手机终端的 IP 是运营商内网的 IP,手机要连接 Internet,就需要通过运营商的网关做一个网络地址转换Network Address Translation,NAT。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯。
  • Android 平台上长连接的实现
    • Timer Android 的 Timer 类可以用来计划需要循环执行的任务,Timer 的问题是它需要用 WakeLock 让 CPU 保持唤醒状态,这样会大量消耗手机电量,大大减短手机待机时间。
    • AlarmManager 这篇文章有介绍怎么使用AlarmManager安卓网络和电量优化 AlarmManager 是 Android 系统封装的用于管理 RTC 的模块,RTC (Real Time Clock) 是一个独立的硬件时钟,可以在 CPU 休眠时正常运行,在预设的时间到达时,通过中断唤醒 CPU。 这意味着,如果我们用 AlarmManager 来定时执行任务,CPU 可以正常的休眠,只有在需要运行任务时醒来一段很短的时间。极光推送的 Android SDK 就是基于这种技术实现的。极光官方文档
  • WebSocket URL的起始输入是ws://或是wss://(在SSL上)。一个带有特定报头的HTTP握手被发送到了服务器端,接着在服务器端或是客户端就可以通过JavaScript来使用某种套接口(socket),这一套接口可被用来通过事件句柄异步地接收数据。
WebSocket 原理
  • WebSocket的协议:在第一次handshake通过以后,连接便建立成功,其后的通讯数据都是以”\x00″开头,以”\xFF”结尾。在客户端,这个是透明的,WebSocket组件会自动将原始数据“掐头去尾”。

request的信息.png

代码语言:javascript
复制
 1GET http://localhost:8080/shiming HTTP/1.1
 2Host: localhost:8080
 3Connection: Upgrade
 4Pragma: no-cache
 5Cache-Control: no-cache
 6Upgrade: websocket
 7Origin: file://
 8Sec-WebSocket-Version: 13
 9User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0
10Accept-Encoding: gzip, deflate, sdch, br
11Accept-Language: zh-CN,zh;q=0.8
12Cookie: _ga=GA1.1.27955907.1529919744
13Sec-WebSocket-Key: PCD+pA79juC6tlBK9zD3Vw==
14Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
  • Sec-WebSocket-Key这个是个随机的值,是一个经过base64编写后的数据Sec-WebSocket-Key: PCD+pA79juC6tlBK9zD3Vw==
  • 然后服务器收到这个请求之后把这个字符串连接上一个固定的字符串 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 为啥是这样的,我目前还不明白,仅仅是自己记录下而已。
  • 最终得到:
代码语言:javascript
复制
1PCD+pA79juC6tlBK9zD3Vw==258EAFA5-E914-47DA-95CA-C5AB0DC85B11
  • 对该字符使用shal 安全散列算法计算出二进制的值,然后用base64 对其进行编码,即可以得到握手的字符串: 8+5CLWTBYLARKoxBxS5uk6s6zZo= ,如下图所示

response信息.png

代码语言:javascript
复制
1HTTP/1.1 101 Switching Protocols
2Upgrade: websocket
3Connection: Upgrade
4Sec-WebSocket-Accept: 8+5CLWTBYLARKoxBxS5uk6s6zZo=
  • Sec-WebSocket-Accept作为响应头的值反馈给客户端。
Go语言实现Websocket
  • 由于Go语言标准包里面没有对WebSocket的支持,但是官方维护的go.net对这个有支持,所以可以获取
代码语言:javascript
复制
1go get golang.org/net/websocket
  • 但是有个小问题,当我 go get后,我在代码中导入包会报错,同时去掉x也不行,所以我在本地目录创建了一个x的目录,然后把net全部放进去了

注意问题.png

导包

  • html 代码
代码语言:javascript
复制
 1<html>
 2<head>
 3    <title>好好学习</title>
 4</head>
 5<body>
 6<script type="text/javascript">
 7    var sock = null;
 8    // var wsuri = "wss://127.0.0.1:8080"; //本地的地址 是可以改变的哦
 9     var wsuri = "ws://localhost:8080/shiming"; //本地的地址 是可以改变的哦
10
11
12    window.onload = function() {
13        //可以看到客户端JS,很容易的就通过WebSocket函数建立了一个与服务器的连接sock,当握手成功后,会触发WebScoket对象的onopen事件,告诉客户端连接已经成功建立。客户端一共绑定了四个事件。
14        console.log("开始了 onload");
15
16        sock = new WebSocket(wsuri);
17        //建立连接后触发
18        sock.onopen = function() {
19            console.log(" 建立连接后触发 connected to " + wsuri);
20        }
21        // 关闭连接时候触发
22        sock.onclose = function(e) {
23            console.log("关闭连接时候触发 connection closed (" + e.code + ")");
24        }
25        // 收到消息后触发
26        sock.onmessage = function(e) {
27            console.log("收到消息后触发 message received: " + e.data);
28        }
29        //发生错误的时候触发
30        sock.onerror=function (e) {
31            console.log("发生错误时候触发"+wsuri)
32        }
33    };
34     //如果sock被关闭掉了 这里 也会报错的啊
35    function send() {
36        var msg = document.getElementById('message').value;
37        sock.send(msg);
38    };
39</script>
40<h1>GoWebSocketDemo</h1>
41<form>
42    <p>
43        Message: <input id="message" type="text" value="你好啊  shiming 小哥哥  嘿嘿   ">
44    </p>
45</form>
46<button onclick="send();">给服务器发送消息</button>
47</body>
48</html>
  • go 代码
代码语言:javascript
复制
 1package main
 2
 3import (
 4    "fmt"
 5    "net/http"
 6    //草拟吗 自己创建的目录 哈哈哈哈哈    还好我比较聪明  要不然 就完蛋了  麻痹
 7    "golang.org/x/net/websocket"
 8    "log"
 9)
10
11func main() {
12    fmt.Println("Go语言标准包里面没有提供对WebSocket的支持,但是在由官方维护的go.net子包中有对这个的支持 go get golang.org/x/net/websocket")
13    //打印这个信息就,os.Exit(1)  退出程序
14    //log.Fatal("shiming")  todo  草拟吗 啊   看清楚啊   后面的域名的地址 有个老子的名字啊
15    http.Handle("/shiming",websocket.Handler(Echo))
16     if err:=http.ListenAndServe(":8080",nil);err!=nil{
17        log.Fatal(err)
18     }
19
20
21}
22
23func Echo(w *websocket.Conn)  {
24    var error error
25    for   {
26        var reply string
27        if  error= websocket.Message.Receive(w,&reply);error!=nil{
28            fmt.Println("不能够接受消息 error==",error)
29            break
30        }
31        fmt.Println("能够接受到消息了--- ",reply)
32        msg:="我已经收到消息 Received:"+reply
33        //  连接的话 只能是   string;类型的啊
34        fmt.Println("发给客户端的消息: "+msg)
35
36        if error = websocket.Message.Send(w, msg); error != nil {
37            fmt.Println("不能够发送消息 悲催哦")
38            break
39        }
40    }
41}
  • 说明一点:http.Handle("/shiming",websocket.Handler(funName)),如果在这里有路由的话,记得在 html中也要改成一样的, html中的代码 :var wsuri = "ws://localhost:8080/shiming"
  • x目录自己创建一个,把net包剪切进去就可以

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。

Golang语言社区

ID:Golangweb

www.bytedancing.com

游戏服务器架构丨分布式技术丨大数据丨游戏算法学习

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-09-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • WebSocket 原理
  • Go语言实现Websocket
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档