如果只是想了解chat的实现方式,在gorilla和revel框架里面都有完整的chat实例可以提供参考。本篇讲解的是,如何基于martini实现websocket的聊天。

配置步骤:

1 已经安装了go命令,配置了GOPATH

2 安装gorilla/websocket

go get github.com/gorilla/websocket

3 安装martini

go get github.com/go-martini/martini

项目文件列表

$GOPATH/demo/home.html
$GOPATH/demo/martini_ws.go

home.html 代码

<!DOCTYPE html>
<html lang="en">
<head>
<title>Chat Example</title>
<script type="text/javascript">
window.onload = function () {
var conn;
var msg = document.getElementById("msg");
var log = document.getElementById("log"); function appendLog(item) {
var doScroll = log.scrollTop === log.scrollHeight - log.clientHeight;
log.appendChild(item);
if (doScroll) {
log.scrollTop = log.scrollHeight - log.clientHeight;
}
} document.getElementById("form").onsubmit = function () {
if (!conn) {
return false;
}
if (!msg.value) {
return false;
}
conn.send(msg.value);
msg.value = "";
return false;
}; if (window["WebSocket"]) {
conn = new WebSocket("ws://{{$}}/ws");
conn.onclose = function (evt) {
var item = document.createElement("div");
item.innerHTML = "<b>Connection closed.</b>";
appendLog(item);
};
conn.onmessage = function (evt) {
var messages = evt.data.split('\n');
for (var i = ; i < messages.length; i++) {
var item = document.createElement("div");
item.innerText = messages[i];
appendLog(item);
}
};
} else {
var item = document.createElement("div");
item.innerHTML = "<b>Your browser does not support WebSockets.</b>";
appendLog(item);
}
};
</script>
<style type="text/css">
html {
overflow: hidden;
} body {
overflow: hidden;
padding: ;
margin: ;
width: %;
height: %;
background: gray;
} #log {
background: white;
margin: ;
padding: .5em .5em .5em .5em;
position: absolute;
top: .5em;
left: .5em;
right: .5em;
bottom: 3em;
overflow: auto;
} #form {
padding: .5em .5em;
margin: ;
position: absolute;
bottom: 1em;
left: 0px;
width: %;
overflow: hidden;
} </style>
</head>
<body>
<div id="log"></div>
<form id="form">
<input type="submit" value="Send" />
<input type="text" id="msg" size=""/>
</form>
</body>
</html>

martini_ws.go代码

package main

import (
"fmt"
"github.com/go-martini/martini"
"github.com/gorilla/websocket"
"log"
"net/http"
"text/template"
) const (
readBufferSize =
writeBufferSize =
) type Client struct {
conn *websocket.Conn
messages chan []byte
} var clients map[*Client]bool // 存储所有的链接
var broadcast chan []byte // 广播聊天的chan
var addClients chan *Client // 新链接进来的chan func (c *Client) readPump() {
for {
_, message, err := c.conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
log.Printf("error: %v", err)
}
break
}
fmt.Printf("receive message is :%s\n", message)
broadcast <- message
}
} func (c *Client) writePump() {
for {
select {
case message := <-c.messages:
fmt.Printf("send message is :%s\n", message)
c.conn.WriteMessage(, message)
}
}
} func manager() { clients = make(map[*Client]bool)
broadcast = make(chan []byte, )
addClients = make(chan *Client) for {
select {
case message := <-broadcast:
for client := range clients {
select {
case client.messages <- message:
default:
close(client.messages)
delete(clients, client)
}
}
case itemClient := <-addClients:
clients[itemClient] = true
}
}
} func main() { var homeTemplate = template.Must(template.ParseFiles("home.html")) m := martini.Classic() m.Get("/", func(res http.ResponseWriter, req *http.Request) { res.Header().Set("Content-Type", "text/html; charset=utf-8")
homeTemplate.Execute(res, req.Host)
}) m.Get("/ws", func(res http.ResponseWriter, req *http.Request) { // res and req are injected by Martini
conn, err := websocket.Upgrade(res, req, nil, readBufferSize, writeBufferSize)
if err != nil {
log.Println(err)
return
}
client := &Client{conn: conn, messages: make(chan []byte, )}
addClients <- client
go client.writePump()
client.readPump()
}) go manager() m.RunOnAddr(":3010")
//m.Run() }

按照上面的步骤建好文件,就可以运行了。m.RunOnAddr 可以改成你需要的端口

执行命令:

go run martini_ws.go

在浏览器输入 http://localhost:3010 就能访问你本机的聊天服务了

参考地址

https://github.com/patcito/martini-gorilla-websocket-chat-example

  

go语言从零学起(四) -- 基于martini和gorilla实现的websocket聊天实例的更多相关文章

  1. go语言从零学起(三) -- chat实现的思考

    要通过go实现一个应用场景: 1 建立一个websocket服务 2 维护在线用户的链接 3 推送消息和接受用户的操作 列出需求,很显然的想到了chat模型.于是研究了revel框架提供的sample ...

  2. go语言从零学起(一) -- 文档教程篇

    先记录一下自己学go语言的出发点 作为一个phper,精通一门底层语言一直是努力的目标. 相对于c,c++,go语言不需要过多的关注指针,内存释放,一两行代码就能跑起一个server服务,简直不要太简 ...

  3. go语言从零学起(二)--list循环删除元素(转载)

    本篇系转载 在使用go的container/list的package时,你可能会无意间踩一个小坑,那就是list的循环删除元素. list删除元素,直观写下来的代码如下: package main i ...

  4. 从零学脚手架(四)---babel

    如果此篇对您有所帮助,在此求一个star.项目地址: OrcasTeam/my-cli 接下来介绍一个打包编译过程中一个极为重要的工具--babel. ES6的枷锁 细心的朋友可以知道,在之前打包编译 ...

  5. 带你从零学ReactNative开发跨平台App开发(四)

    ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...

  6. 带你从零学ReactNative开发跨平台App开发-[react native 仿boss直聘](十三)

    ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...

  7. 带你从零学ReactNative开发跨平台App开发[expo 打包发布](八)

    ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...

  8. 从头开始学JavaScript (四)——操作符

    原文:从头开始学JavaScript (四)--操作符 一.一元操作符 1.自增自减操作符:分为前置型和后置型: 前置型:++a;--a; 后置型:a++;a--; 例: <script typ ...

  9. C语言老司机学Python (五)

    今天看的是标准库概览. 操作系统接口: 用os模块实现. 针对文件和目录管理,还有个shutil模块可以用. 例句: import os os.getcwd() # 返回当前的工作目录 os.chdi ...

随机推荐

  1. 【个人博客作业II】代码复审结果

    [代码复审结果] General Does the code work? Does it perform its intended function, the logic is correct etc ...

  2. linux 第七周 总结及实验

    姬梦馨 原创作品 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 第七周 Linux内核如何装载和启动一 ...

  3. 个人git链接和git学习心得总结

    个人git链接和git学习心得总结 个人git链接: https://github.com/hanzhaoyan Git 是 Linux 的创始人 Linus Torvalds 开发的开源和免费的版本 ...

  4. 20150421 作业5 四则运算 测试与封装 5.1 5.2(doing)

    结伴队友:王佳寧,他的博客地址:http://www.cnblogs.com/paopaotai/ 5.2 黑白盒測試 測試項目名稱 黑盒測試 測試人員 葉子鵬&王佳寧 測試編號 測試頁面 測 ...

  5. 通过LVM给Linux扩容

    主要参考以下两篇文章: 1:https://www.cnblogs.com/sixiweb/p/3360008.html 2:https://wenku.baidu.com/view/42deee1a ...

  6. linux和Mac上安装composer

    使用命令行方式,可以直接使用下面的命令,顺序执行: php -r "copy ('https://getcomposer.org/installer','composer-setup.php ...

  7. jq源码解析之绑在$,jQuery上面的方法

    1.当我们用$符号直接调用的方法.在jQuery内部是如何封装的呢?有没有好奇心? // jQuery.extend 的方法 是绑定在 $ 上面的. jQuery.extend( { //expand ...

  8. python 协程库gevent学习--gevent数据结构及实战(三)

    gevent学习系列第三章,前面两章分析了大量常用几个函数的源码以及实现原理.这一章重点偏向实战了,按照官方给出的gevent学习指南,我将依次分析官方给出的7个数据结构.以及给出几个相应使用他们的例 ...

  9. 关于utf8mb4的学习了解笔记

    占位下班写 据说可以存储emoji ..妈蛋今天大神又秀我一脸 大概意思是,我们整个后端数据库,最近都升级了编码格式.从以前久的utf-8整个升级到了utf8mb4的格式 该格式支持emoji表情. ...

  10. servlet生成验证码代码

    package forward; import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt ...