项目 例子已发布到 github 欢迎 Starvue
项目地址git
下载地址github
一路狂点 nextgolang
检查是否安装成功 命令行输入web
go version
复制代码
brew install go
复制代码
下载vue-cli
安装json
验证vim
建立 hello.go 文件windows
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
复制代码
运行跨域
go run hello.go
复制代码
运行
go build hello.go
./hello
复制代码
vim ~/.zshrc 或者 vim .bash_profile
export GOROOT=/usr/local/go
# 项目目录
export GOPATH=~/go
export PATH=${PATH}:$GOPATH/bin
复制代码
执行 source ~/.zshrc 或 source ~/.bash_profile 生效
检查命令
go env
复制代码
WebSocket 协议在2008年诞生,2011年成为国际标准。全部浏览器都已经支持了。
它的最大特色就是,服务器能够主动向客户端推送信息,客户端也能够主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
go的 websocket 库
获取方式
go get github.com/gorilla/websocket
复制代码
src 为 go程序目录 web // vue-cli 构建的项目 go.mod 是 依赖包的管理(记录和解析对其余模块的依赖性)
生成方式 执行如下命令
cd RealTimeChat
go mod init src // init 后 跟 main.js所在的目录名称
复制代码
web 项目建立 请移动至
package main
import (
"encoding/json" // json格式化
"fmt"
"net/http" // http 服务
"github.com/gorilla/websocket"
)
// map 映射,其键对应是一个指向 WebSocket 的指针,其值就是一个布尔值。咱们实际上并不须要这个值,但使用的映射数据结构须要有一个映射值,这样作更容易添加和删除单项。
var clients = make(map[*websocket.Conn]bool)
// 由客户端发送消息的队列
var broadcast = make(chan Message)
// Upgrader 用于升级 http 请求,把 http 请求升级为长链接的 WebSocket
var upgrader = websocket.Upgrader{
// 解决跨域问题
CheckOrigin: func(r *http.Request) bool {
return true
},
}
// 客户端惟一id
type userInfo struct {
UserId string
Code string
}
// 用户信息+消息内容
type Message struct {
Msg string `json:"msg"`
Username string `json:"username"`
}
// Upgrade 函数将 http 升级到 WebSocket 协议
func handler(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
// 获取id
var info userInfo
info.UserId = ws.RemoteAddr().String()
info.Code = "auth"
data, _ := json.Marshal(info)
// 下发id
ws.WriteMessage(websocket.TextMessage, []byte(string(data)))
fmt.Println("用户:", ws.RemoteAddr().String(), "加入")
if err != nil {
fmt.Println(err)
return
}
// 退出时关闭链接
defer ws.Close()
// 把新的客户端添加到全局的 "clients" 映射表中进行注册
clients[ws] = true
// 处理WebSocket的先消息
for {
var msg Message
// 从链接中读取下一个JSON编码的消息,并将其存储在msg指向的值中。
err := ws.ReadJSON(&msg)
if err != nil {
fmt.Println(err)
delete(clients, ws)
break
}
// 将新接收到的消息发送到广播频道
broadcast <- msg
}
}
// 广播消息
func handleMessages() {
for {
// 从“broadcast”中连续读取数据
msg := <-broadcast
// 经过各自的 WebSocket 链接将消息传播到全部客户端
for client := range clients {
fmt.Println('2')
// WriteJSON将msg的JSON编码写为消息
err := client.WriteJSON(&msg)
if err != nil {
fmt.Println(err)
client.Close()
delete(clients, client)
}
}
}
}
func main() {
// 打印输出信息。
fmt.Println("ListenAndServe: 8000")
// http 服务
http.HandleFunc("/ws", handler)
go handleMessages()
err := http.ListenAndServe(":8000", nil)
if err != nil {
fmt.Println("ListenAndServe")
fmt.Println(err)
}
}
复制代码
src 目录下运行
go run main.go
复制代码
...
mounted() {
var self = this;
this.ws = new WebSocket('ws://localhost:8000/ws');
// 接收消息
this.ws.addEventListener('message', function(e) {
var res = JSON.parse(e.data);
// 判断 是否为 下发惟一用户id
if(res.Code === 'auth'){
self.form.username = res.UserId.replace(RegExp('\\[::1]:', 'g'), '')
self.upUSER_ID(self.form.username)
return
}
// 消息类型,本身仍是别人,right 是本身
var type = res.username == self.userid ? 'right' : 'left'
// 存储消息 到 store
self.addMessage(Object.assign({
type: type
},res))
});
},
methods:{
...mapActions('user', ['upUSER_ID']),
...mapActions('message', ['addMessage']),
// 发送消息
submit() {
this.ws.send(
JSON.stringify({
msg: this.form.msg,
username: this.form.username
}));
this.form.msg = ''
},
}
...
复制代码
go run main.go
ListenAndServe: 8000
用户: [::1]:55023 加入
用户: [::1]:55055 加入
websocket: close 1001 (going away)
用户: [::1]:55062 加入
复制代码
未完待续,功能作的比较简易,以前设想的 注册登陆, 好友列表,聊天记录,发送私信 ,因时间有限 还没来得及实现,后续后继续完善
欢迎在评论区留言,能够的话