Golang——WebSocket

拉模式与推送模式

拉模式的缺点 数据更新频率低,则大多数的请求是无效的
在线用户数量多,则服务端的查询负载高。
定时查询拉取,无法满足时效性要求
推送模式 尽在数据更新才推送,需要维护大量的在线长连接,数据更新后立即推送。

WebSocket推送

浏览器支持的socket编程,轻松维护服务端长连接,基于TCP可靠传输之上的协议,无需开发者关心通讯细节。提供了高度抽象的编程接口,业务开发成本低。

websocket协议

来源于慕课网

协议升级后,继续复用HTTP的底层socket完成后续操作
message底层被切分成多个frame 帧传输。
编程是只需要操作message不需要关心frame
框架底层完成TCP网络I/O,WebSocker协议解析,开发者不需要关心。

package main

import "net/http"

func wsHandle(writer http.ResponseWriter, request *http.Request) {
      writer.Write([]byte("hello world"))
}

func main() {
    http.HandleFunc("/ws", wsHandle)
    http.ListenAndServe(":8888",nil)
    
}

服务请求参数

Request URL: http://localhost:8888/ws
Request Method: GET
Status Code: 200 OK
Remote Address: [::1]:8888

websocket的服务器端代码

package main

import (
    "fmt"
    "github.com/gorilla/websocket"
    "net/http"
    "time"
)

func wsHandle(writer http.ResponseWriter, request *http.Request) {
    upgrader:= websocket.Upgrader{CheckOrigin: func(r *http.Request) bool {
          return true
      }}
    con,err := upgrader.Upgrade(writer,request,nil)
    defer con.Close()
    if err!=nil {
        writer.Write([]byte(err.Error()))
    }
    for{
        _, p, err := con.ReadMessage()
        if err!= nil {
            writer.Write([]byte(err.Error()))
            break
        }
        fmt.Println("client message "+string(p))
        con.WriteMessage(websocket.TextMessage,[]byte(time.Now().String()))
    }
}

func main() {
    http.HandleFunc("/ws", wsHandle)
    http.ListenAndServe(":8888",nil)
    
}
image.png

websocket 客户端代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <script>
        window.addEventListener("load", function(evt) {
            var output = document.getElementById("output");
            var input = document.getElementById("input");
            var ws;
            var print = function(message) {
                var d = document.createElement("div");
                d.innerHTML = message;
                output.appendChild(d);
            };
            document.getElementById("open").onclick = function(evt) {
                if (ws) {
                    return false;
                }
                ws = new WebSocket("ws://localhost:8888/ws");
                ws.onopen = function(evt) {
                    print("连接websocket");
                }
                ws.onclose = function(evt) {
                    print("CLOSE");
                    ws = null;
                }
                ws.onmessage = function(evt) {
                    print("收到消息: " + evt.data);
                }
                ws.onerror = function(evt) {
                    print("ERROR: " + evt.data);
                }
                return false;
            };
            document.getElementById("send").onclick = function(evt) {
                if (!ws) {
                    return false;
                }
                print("发送消息: " + input.value);
                ws.send(input.value);
                return false;
            };
            document.getElementById("close").onclick = function(evt) {
                if (!ws) {
                    return false;
                }
                ws.close();
                return false;
            };
        });
    </script>
</head>
<body>
<table>
    <tr><td valign="top" width="50%">
            <p>点击启动按钮创建websocket连接<br/>
               点击发送按钮可以发送任意消息给服务器<br/>
               点击关闭按钮断开websocket连接
            </p>
            <form>
                <button id="open">启动</button>
                <button id="close">关闭</button>
                <input id="input" type="text" value="Hello golang!">
                <button id="send">发送</button>
            </form>
        </td><td valign="top" width="50%">
            <div id="output"></div>
        </td></tr></table>
</body>
</html>

运行client.html,效果如下



数据抓包


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容

  • (非转载) "我就三千工资,还要养活全家人,承受不起这制氧机的价钱" 这是今天遇到的一个客人,母亲三高,打算给他母...
    无所谓姑凉阅读 254评论 0 0
  • 我是六扇帽扇,错号,留三毛三 我是一个男生,可是我爱画画,除了美术课我什么课都不喜欢, 我有一个爱唠叨的妈妈,...
    疯狂写作阅读 194评论 0 0
  • 小豆豆终于见到了校长先生,而且校长先生主动要求和小豆豆谈话。即使小豆豆的说话的顺序、说话的方式,都有些乱七八糟...
    成长的路上有您结伴而行阅读 206评论 0 0
  • 阅读书目:《周一清晨的领导课》 阅读时长:2小时左右 阅读收获:今天去医院做糖筛顺便看了这本书的第一章,和老公顺便...
    小梦化蝶阅读 203评论 0 0
  • 更喜欢的一方能有多卑微呢 真的太可怜了
    阿月的小蝴蝶阅读 102评论 0 0