前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go语言+vue实现实时聊天

go语言+vue实现实时聊天

原创
作者头像
iwhao
发布2024-07-03 23:40:08
590
发布2024-07-03 23:40:08

安装篇

windows

一路狂点 next

检查是否安装成功 命令行输入

代码语言:go
复制
     go version

mac

方法一
代码语言:shell
复制
    brew install go
方法二 比较快

下载

安装

验证

万能的 hello word

创建 hello.go 文件

代码语言:go
复制
    package main

    import "fmt"
    
    func main() {
       fmt.Println("Hello, World!")
    }

运行

代码语言:shell
复制
    go run hello.go

运行

代码语言:shell
复制
    go build hello.go
    ./hello

VsCode 扩展

镜像代理-Goproxy 中国

环境变量

代码语言:shell
复制
vim ~/.zshrc 或者 vim .bash_profile

    export GOROOT=/usr/local/go
    # 项目目录
    export GOPATH=~/go  
    export PATH=${PATH}:$GOPATH/bin

执行 source ~/.zshrc 或 source ~/.bash_profile 生效

检查命令

代码语言:shell
复制
    go env

WebSocket

WebSocket 协议在2008年诞生,2011年成为国际标准。所有浏览器都已经支持了。

它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

gorilla/websocket

go的 websocket 库

获取方式

代码语言:shell
复制
    go get github.com/gorilla/websocket

进入主题

项目结构

  • realTimeChat
    • src
      • main.js
    • web
    • go.mod

src 为 go程序目录

web // vue-cli 构建的项目

go.mod 是 依赖包的管理(记录和解析对其他模块的依赖性)

生成方式 执行以下命令

代码语言:shell
复制
    cd RealTimeChat
    go mod init src // init 后 跟 main.js所在的目录名称

主程序 main.go

代码语言:go
复制
    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 目录下运行

代码语言:shell
复制
    go run main.go

web vue主逻辑

代码语言:js
复制
    ...
    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 = ''
        },  
    }
    ...

效果图

代码语言:shell
复制
    go run main.go
    ListenAndServe: 8000
    用户: [::1]:55023 加入
    用户: [::1]:55055 加入
    websocket: close 1001 (going away)
    用户: [::1]:55062 加入

未完待续,功能做的比较简易,之前设想的 注册登录, 好友列表,聊天记录,发送私信 ,因时间有限 还没来得及实现,后续后继续完善

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装篇
    • windows
      • mac
      • 万能的 hello word
      • VsCode 扩展
      • 环境变量
      • WebSocket
      • gorilla/websocket
      • 进入主题
        • 项目结构
          • 主程序 main.go
            • web vue主逻辑
            • 效果图
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档