html5 聊天 一对一,gin websocket 一对一聊天

依赖包github.com/gin-gonic/gin

github.com/gorilla/websocket

代码

创建ws/ws.gopackage ws

import (

"encoding/json"

"github.com/gin-gonic/gin"

"github.com/gorilla/websocket"

"log"

"net/http"

)

// ClientManager is a websocket manager

type ClientManager struct {

Clients map[string]*Client

Broadcast chan []byte

Register chan *Client

Unregister chan *Client

}

// Client is a websocket client

type Client struct {

ID string

Socket *websocket.Conn

Send chan []byte

}

// Message is return msg

type Message struct {

Sender string `json:"sender,omitempty"`

Recipient string `json:"recipient,omitempty"`

Content string `json:"content,omitempty"`

}

// Manager define a ws server manager

var Manager = ClientManager{

Broadcast: make(chan []byte),

Register: make(chan *Client),

Unregister: make(chan *Client),

Clients: make(map[string]*Client),

}

// Start is 项目运行前, 协程开启start -> go Manager.Start()

func (manager *ClientManager) Start() {

for {

log.Println("")

select {

case conn :=

log.Printf("新用户加入:%v", conn.ID)

Manager.Clients[conn.ID] = conn

jsonMessage, _ := json.Marshal(&Message{Content: "Successful connection to socket service"})

conn.Send

case conn :=

log.Printf("用户离开:%v", conn.ID)

if _, ok := Manager.Clients[conn.ID]; ok {

jsonMessage, _ := json.Marshal(&Message{Content: "A socket has disconnected"})

conn.Send

close(conn.Send)

delete(Manager.Clients, conn.ID)

}

case message :=

MessageStruct :=Message{}

json.Unmarshal(message, &MessageStruct)

for id, conn := range Manager.Clients {

if id!=creatId(MessageStruct.Recipient,MessageStruct.Sender){

continue

}

select {

case conn.Send

default:

close(conn.Send)

delete(Manager.Clients, conn.ID)

}

}

}

}

}

func creatId(uid,touid string) string {

return uid+"_"+touid

}

func (c *Client) Read() {

defer func() {

Manager.Unregister

c.Socket.Close()

}()

for {

c.Socket.PongHandler()

_, message, err := c.Socket.ReadMessage()

if err != nil {

Manager.Unregister

c.Socket.Close()

break

}

log.Printf("读取到客户端的信息:%s", string(message))

Manager.Broadcast

}

}

func (c *Client) Write() {

defer func() {

c.Socket.Close()

}()

for {

select {

case message, ok :=

if !ok {

c.Socket.WriteMessage(websocket.CloseMessage, []byte{})

return

}

log.Printf("发送到到客户端的信息:%s", string(message))

c.Socket.WriteMessage(websocket.TextMessage, message)

}

}

}

//TestHandler socket 连接 中间件 作用:升级协议,用户验证,自定义信息等

func WsHandler(c *gin.Context) {

uid := c.Query("uid")

touid := c.Query("to_uid")

conn, err := (&websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }}).Upgrade(c.Writer, c.Request, nil)

if err != nil {

http.NotFound(c.Writer, c.Request)

return

}

//可以添加用户信息验证

client := &Client{

ID: creatId(uid,touid),

Socket: conn,

Send: make(chan []byte),

}

Manager.Register

go client.Read()

go client.Write()

}

创建main.gopackage main

import (

"github.com/gin-gonic/gin"

"im/ws"

)

//server

func main() {

gin.SetMode(gin.ReleaseMode) //线上环境

go ws.Manager.Start()

r := gin.Default()

r.GET("/ws",ws.WsHandler)

r.GET("/pong", func(c *gin.Context) {

c.JSON(200, gin.H{

"message": "pong",

})

})

r.Run(":8282") // listen and serve on 0.0.0.0:8080

}

运行服务端go run mian.go

创建client.html

Golang Chat

$(function() {

function getUrlParam(name)

{

var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象

var r = window.location.search.substr(1).match(reg); //匹配目标参数

if (r!=null) return unescape(r[2]); return null; //返回参数值

}

var conn;

var msg = $("#msg");

var log = $("#log");

uid=getUrlParam("uid");

to_uid=getUrlParam("to_uid");

function appendLog(msg) {

var d = log[0]

var doScroll = d.scrollTop == d.scrollHeight - d.clientHeight;

msg.appendTo(log)

if (doScroll) {

d.scrollTop = d.scrollHeight - d.clientHeight;

}

}

$("#form").submit(function() {

if (!conn) {

return false;

}

if (!msg.val()) {

return false;

}

var json = {"sender":uid,"recipient":to_uid,"content":msg.val()}; //创建对象;

var jsonStr = JSON.stringify(json); //转为JSON字符串

conn.send(jsonStr);

msg.val("");

return false

});

if (window["WebSocket"]) {

conn = new WebSocket("ws://localhost:8282/ws?uid="+uid+"&to_uid="+to_uid);

conn.onclose = function(evt) {

appendLog($("

Connection Closed.
"))

}

conn.onmessage = function(evt) {

appendLog($("

}

} else {

appendLog($("

WebSockets Not Support.
"))

}

});

html {

overflow: hidden;

}

body {

overflow: hidden;

padding: 0;

margin: 0;

width: 100%;

height: 100%;

background: gray;

}

#log {

background: white;

margin: 0;

padding: 0.5em 0.5em 0.5em 0.5em;

position: absolute;

top: 0.5em;

left: 0.5em;

right: 0.5em;

bottom: 3em;

overflow: auto;

}

#form {

padding: 0 0.5em 0 0.5em;

margin: 0;

position: absolute;

bottom: 1em;

left: 0px;

width: 100%;

overflow: hidden;

}

自己搭建nginx或apache等web服务,分别在两个窗口运行

这样就可以聊天了

links上一节:

下一节:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值