golang gorilla websocket例子
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范。
在golang语言中,目前有两种比较常用的实现方式:一个是golang自带的库,另一个是gorilla,功能强大。
golang自带库的使用例子可参考以前的博文:Golang如何使用websocket
本文以gorilla为例,介绍websocket的使用。
下载gorilla
# go get github.com/gorilla/websocket
下面例子中主要包括两部分,server和client。
client部分又包括:web client(浏览器)和非web client。
server
server端是一个HTTP 服务器,监听8080端口。
当接收到连接请求后,将连接使用的http协议升级为websocket协议。后续通信过程中,使用websocket进行通信。
对每个连接,server端等待读取数据,读到数据后,打印数据,然后,将数据又发送给client.
server启动方式
# go run server.go
server.go代码如下:
// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
package main
import (
"flag"
"html/template"
"log"
"net/http"
"github.com/gorilla/websocket"
)
var addr = flag.String("addr", "localhost:8080", "http service address")
var upgrader = websocket.Upgrader{} // use default options
func echo(w http.ResponseWriter, r *http.Request) {
c, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Print("upgrade:", err)
return
}
defer c.Close()
for {
mt, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
break
}
log.Printf("recv: %s", message)
err = c.WriteMessage(mt, message)
if err != nil {
log.Println("write:", err)
break
}
}
}
func home(w http.ResponseWriter, r *http.Request) {
homeTemplate.Execute(w, "ws://"+r.Host+"/echo")
}
func main() {
flag.Parse()
log.SetFlags(0)
http.HandleFunc("/echo", echo)
http.HandleFunc("/", home)
log.Fatal(http.ListenAndServe(*addr, nil))
}
var homeTemplate = template.Must(template.New("").Parse(`
<!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.onopen = function(evt) {
print("OPEN");
}
ws.onclose = function(evt) {
print("CLOSE");
ws = null;
}
ws.onmessage = function(evt) {
print("RESPONSE: " + evt.data);
}
ws.onerror = function(evt) {
print("ERROR: " + evt.data);
}
return false;
};
document.getElementById("send").onclick = function(evt) {
if (!ws) {
return false;
}
print("SEND: " + 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>Click "Open" to create a connection to the server,
"Send" to send a message to the server and "Close" to close the connection.
You can change the message and send multiple times.
<p>
<form>
<button id="open">Open</button>
<button id="close">Close</button>
<p><input id="input" type="text" value="Hello world!">
<button id="send">Send</button>
</form>
</td><td valign="top" width="50%">
<div id="output"></div>
</td></tr></table>
</body>
</html>
`))
server output:
recv: 2018-10-20 17:09:12.497129965 +0800 CST m=+1.010137585
recv: 2018-10-20 17:09:13.495602484 +0800 CST m=+2.008641088
recv: 2018-10-20 17:09:14.49401062 +0800 CST m=+3.007080206
recv: 2018-10-20 17:09:15.497114615 +0800 CST m=+4.010215329
recv: 2018-10-20 17:09:16.494394706 +0800 CST m=+5.007526368
read: websocket: close 1000 (normal)
非web client
client启动后,首先连接server。
连接建立后,主routine每一秒钟向server发送消息(当前时间)。
另一个routine从server接收数据,并打印。
当client退出时,会向server发送关闭消息。接着,等待退出。
client启动方式
# go run client.go
client代码如下:
// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
package main
import (
"flag"
"log"
"net/url"
"os"
"os/signal"
"time"
"github.com/gorilla/websocket"
)
var addr = flag.String("addr", "localhost:8080", "http service address")
func main() {
flag.Parse()
log.SetFlags(0)
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
u := url.URL{Scheme: "ws", Host: *addr, Path: "/echo"}
log.Printf("connecting to %s", u.String())
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
if err != nil {
log.Fatal("dial:", err)
}
defer c.Close()
done := make(chan struct{})
go func() {
defer close(done)
for {
_, message, err := c.ReadMessage()
if err != nil {
log.Println("read:", err)
return
}
log.Printf("recv: %s", message)
}
}()
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for {
select {
case <-done:
return
case t := <-ticker.C:
err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
if err != nil {
log.Println("write:", err)
return
}
case <-interrupt:
log.Println("interrupt")
// Cleanly close the connection by sending a close message and then
// waiting (with timeout) for the server to close the connection.
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
if err != nil {
log.Println("write close:", err)
return
}
select {
case <-done:
case <-time.After(time.Second):
}
return
}
}
}
client output:
connecting to ws://localhost:8080/echo
recv: 2018-10-20 17:09:12.497129965 +0800 CST m=+1.010137585
recv: 2018-10-20 17:09:13.495602484 +0800 CST m=+2.008641088
recv: 2018-10-20 17:09:14.49401062 +0800 CST m=+3.007080206
recv: 2018-10-20 17:09:15.497114615 +0800 CST m=+4.010215329
recv: 2018-10-20 17:09:16.494394706 +0800 CST m=+5.007526368
^Cinterrupt
read: websocket: close 1000 (normal)
web client
web client,也就是使用浏览器。
在浏览器中输入http://127.0.0.1:8080
"Open",然后"send"
server output:
recv: Hello world!!
参考
百度百科
https://baike.baidu.com/item/WebSocket
github
https://github.com/gorilla/websocket
doc
https://godoc.org/github.com/gorilla/websocket
example
https://github.com/gorilla/websocket/blob/master/examples/
golang gorilla websocket例子的更多相关文章
- golang实现WebSocket的商业化使用的开发逻辑(1)
WebSocket是什么 WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议.其最大特点之一就是:服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对 ...
- golang之websocket 源码分析
下载go的websocket包. 1. 通过google官方的方法, 需要hg来同步代码. 由于墙的原因, 还需要设置代理. 比较麻烦 2. http://gopm.io/ 通过该网站下载, 这是go ...
- 带ssl的websocket例子
还是在那个websocket_demo的例子 rebar-creator create-app websocket_demo tree一下看看大概目录 ├── cert │ ├── cowboy- ...
- golang 移动应用例子 example/basic 源码框架分析
条件编译 我们在源码中可以看到2个文件: main.go 和 main_x.go 这两个包名都是 package main , 都有 main 函数. 不会冲突么? 答案是不会的, main_x.go ...
- (网页)websocket例子
转载自博客园张果package action; import javax.websocket.CloseReason; import javax.websocket.OnClose; import j ...
- 基于netty的websocket例子
nettyServer package com.atguigu.netty.websocket; import javax.annotation.PostConstruct; import org.s ...
- erlang的websocket例子
创建工程 rebar-creator create-app websocket_demo 文件列表 route_helper.erl -module(route_helper). -export([g ...
- Springboot WebSocket例子
Springboot整合WebSocket 1.application.properties #设置服务端口号 server.port=8080 #thymeleaf配置 #是否启用模板缓存. spr ...
- golang LMDB入门例子——key range查询
如下,使用gomb库 package main import ( "bytes" "fmt" "io/ioutil" "os&qu ...
随机推荐
- 【Python】xml遍历练习
<?xml version="1.0" encoding="utf-8" ?> <!--this is a test about xml. ...
- nodejs的express框架
介绍: Express是由路由和中间件构成一个的nodejs的一种web应用框架; 功能: 可以设置中间件来响应 HTTP 请求. 定义了路由表用于执行不同的 HTTP 请求动作. 可以通过向模板传递 ...
- simhash
1,SimHash https://yanyiwu.com/work/2014/01/30/simhash-shi-xian-xiang-jie.html 64位Hash为什么海明距离选3? http ...
- vmware安装centos问题
* 选择安装后,一直黑屏 重新启动电脑,在启动界面进入BIOS设置,找到Intel (R) Virtualization Technology,设置成Enabled,保存设置以后重新启动电脑,问题解决 ...
- 全局(Global) 与本地(Local)索引的区别
一.定义说明 oracle数据库中,存在多种对象,最常见的表和索引,索引的目的是为了加快查询:oracle建议一个表>2g时,就建议进行分区,分区表的好处此处省略,分区表有维护操作,但是某些维护 ...
- Vim正则表达式匹配替换字符串
/********************************************************************** * Vim正则表达式匹配替换字符串 * 说明: * 用V ...
- javascript的this多种场景用法
作者:刘志祥 时间:2017.11.10 参考:阮一峰的官方网站 this 是javaScript中的一个关键字,只能在函数内使用.随着场合的不同,this的值会发生变化. 1. 单纯的全局函数调用, ...
- s21day01 python笔记
s21day01 python笔记 一.计算机基础 计算机的初步认识 用户:人 软件:QQ.浏览器等 解释器/编译器/虚拟机:java解释器.python解释器等 操作系统 硬件:CPU.内存.硬盘. ...
- 如何更改Apache的根目录指向
更改Apache的默认网站根目录地址方法如下: 0,先找到主目录下的apache文件,然后进行下面操作 1.找到 DocumentRoot “X:/Apache/htdocs” 将“X:/Apache ...
- document.write中输出html标签用法
输出HTML标签,只需将标签写入双引号: 示例:在网页中输出<p>革命还在继续</p> document.write("<p style='border:1px ...