服务端监听聊天代码,功能是在指定的room的人能互相看到聊天信息
package controllers
import (
"encoding/json"
"fmt"
"log"
"github.com/astaxie/beego"
"github.com/gorilla/websocket"
)
type WsController struct {
beego.Controller
}
func (this *WsController) Join() {
username := this.GetString("username")
room := this.GetString("room")
if (len(username)) == 0 {
this.Redirect("/", 302)
return
}
if (len(room)) == 0 {
this.Redirect("/", 302)
return
}
this.Data["room"] = room
this.Render()
}
var (
subscribe chan *Subscriber
broadcast chan []byte
clients map[*Subscriber]bool
)
type Subscriber struct {
username string
room string
conn *websocket.Conn
messages chan []byte
}
func (c *Subscriber) writePump() {
for {
select {
case message := <-c.messages:
fmt.Printf("send message is :%s\n", message)
c.conn.WriteMessage(1, message)
}
}
}
func manager() {
clients = make(map[*Subscriber]bool)
broadcast = make(chan []byte, 10)
subscribe = make(chan *Subscriber)
for {
select {
case tmpClient := <-broadcast:
for client := range clients {
clientInfo := make(map[string]string)
json.Unmarshal([]byte(tmpClient), &clientInfo)
if clientInfo["room"] == client.room {
select {
case client.messages <- tmpClient:
default:
close(client.messages)
delete(clients, client)
}
}
}
case itemClient := <-subscribe:
clients[itemClient] = true
}
}
}
func (c *Subscriber) readPump() {
for {
_, message, err := c.conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway) {
log.Printf("error: %v", err)
}
break
}
var info = make(map[string]string)
info["username"] = c.username
info["room"] = c.room
info["message"] = string(message)
tmpInfo, _ := json.Marshal(info)
fmt.Printf("receive message is :%s\n", tmpInfo)
broadcast <- tmpInfo
}
}
func (this *WsController) Get() {
username := this.GetString("username")
room := this.GetString("room")
if (len(username)) == 0 {
this.Redirect("/", 302)
return
}
if (len(room)) == 0 {
this.Redirect("/", 302)
return
}
conn, err := websocket.Upgrade(this.Ctx.ResponseWriter, this.Ctx.Request, nil, 1024, 1024)
if err != nil {
log.Println(err)
return
}
subTmp := &Subscriber{username: username, room: room, conn: conn, messages: make(chan []byte, 5)}
subscribe <- subTmp
go subTmp.writePump()
subTmp.readPump()
}
func init() {
go manager()
}
join的view代码
<!DOCTYPE html>
<html>
<head>
<title>{{.room}}号房间-测试聊天室</title>
</head>
<body>
<script src="static/js/jquery-3.2.1.min.js"></script>
<script>
$(function(){
var conn;
if (window["WebSocket"]) {
conn = new WebSocket("ws://" + document.location.host + '/ws' + document.location.search);
conn.onclose = function (evt) {
$('.close').html("websocket connect close~");
};
conn.onmessage = function (evt) {
var messages = evt.data.split('\n');
for (var i = 0; i < messages.length; i++) {
message = $.parseJSON(messages[i]);
tmpData = message.username + "说:" + message.message
$('.messages').append(tmpData + "<br/>");
}
};
} else {
var item = document.createElement("div");
item.innerHTML = "<b>Your browser does not support WebSockets.</b>";
appendLog(item);
}
$('.submit').on('click',function(){
if (!conn) {
return false;
}
if(!$('.msg').val()){
return false;
}
conn.send($('.msg').val())
$('.msg').val('');
return false;
})
});
</script>
<div class="close"></div>
<div class="messages"></div>
<input text="text" id="msg" class="msg" />
<input type="button" value="提交信息" class="submit" />
</body>
</html>