項目 例子已發佈到 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 加入
複製代碼
未完待續,功能作的比較簡易,以前設想的 註冊登陸, 好友列表,聊天記錄,發送私信 ,因時間有限 還沒來得及實現,後續後繼續完善
歡迎在評論區留言,能夠的話