Golang实现基于Websocket协议的H5聊天室

前端之家收集整理的这篇文章主要介绍了Golang实现基于Websocket协议的H5聊天室前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

http://www.cnblogs.com/wangrudong003/p/5535689.html

go代码部分:

// WebChat project main.go
package main

import (
	"fmt"
	"net/http"
	"time"

	"encoding/json"

	"strings"

	"golang.org/x/net/websocket"
)

//全局信息
var datas Datas
var users map[*websocket.Conn]string

func main() {
	fmt.Println("启动时间")
	fmt.Println(time.Now())

	//初始化
	datas = Datas{}
	users = make(map[*websocket.Conn]string)

	//绑定效果页面
	http.HandleFunc("/",h_index)
	//绑定socket方法
	http.Handle("/webSocket",websocket.Handler(h_webSocket))
	//开始监听
	http.ListenAndServe(":8080",nil)
}

func h_index(w http.ResponseWriter,r *http.Request) {

	http.ServeFile(w,r,"index.html")
}

func h_webSocket(ws *websocket.Conn) {

	var userMsg UserMsg
	var data string
	for {

		//判断是否重复连接
		if _,ok := users[ws]; !ok {
			users[ws] = "匿名"
		}
		userMsgsLen := len(datas.UserMsgs)
		fmt.Println("UserMsgs",userMsgsLen,"users长度:",len(users))

		//有消息时,全部分发送数据
		if userMsgsLen > 0 {
			b,errMarshl := json.Marshal(datas)
			if errMarshl != nil {
				fmt.Println("全局消息内容异常...")
				break
			}
			for key,_ := range users {
				errMarshl = websocket.Message.Send(key,string(b))
				if errMarshl != nil {
					//移除出错的链接
					delete(users,key)
					fmt.Println("发送出错...")
					break
				}
			}
			datas.UserMsgs = make([]UserMsg,0)
		}

		fmt.Println("开始解析数据...")
		err := websocket.Message.Receive(ws,&data)
		fmt.Println("data:",data)
		if err != nil {
			//移除出错的链接
			delete(users,ws)
			fmt.Println("接收出错...")
			break
		}

		data = strings.Replace(data,"\n","",0)
		err = json.Unmarshal([]byte(data),&userMsg)
		if err != nil {
			fmt.Println("解析数据异常...")
			break
		}
		fmt.Println("请求数据类型:",userMsg.DataType)

		switch userMsg.DataType {
		case "send":
			//赋值对应的昵称到ws
			if _,ok := users[ws]; ok {
				users[ws] = userMsg.UserName

				//清除连接人昵称信息
				datas.UserDatas = make([]UserData,0)
				//重新加载当前在线连接人
				for _,item := range users {

					userData := UserData{UserName: item}
					datas.UserDatas = append(datas.UserDatas,userData)
				}
			}
			datas.UserMsgs = append(datas.UserMsgs,userMsg)
		}
	}

}

type UserMsg struct {
	UserName string
	Msg      string
	DataType string
}

type UserData struct {
	UserName string
}

type Datas struct {
	UserMsgs  []UserMsg
	UserDatas []UserData
}

html5代码部分:(index.html 和main.go放置到同一目录)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <title></title>
    <Meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
    <!-- 新 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
    <!--        <script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>-->
</head>
<body>
    <div class="container">
        <div>内容:</div>
        <div class="list-group" id="divShow">
            <!--<div class="list-group-item list-group-item-success">1111</div>
            <div class="list-group-item list-group-item-info">1111</div>
            <div class="list-group-item list-group-item-warning">1111</div>
            <div class="list-group-item list-group-item-danger">1111</div>-->
        </div>
        <div class="list-group" id="divUsers">
            在线:<br />
            <!--<div class="btn btn-default">111</div>-->

        </div>
        <div>
            昵称:<input class="form-control" id="txtUserName" value="红领巾" type="text" maxlength="20" style="width: 30%; margin-bottom: 15px" />
            聊聊:<textarea class="form-control" id="txtContent" autofocus rows="6" placeholder="想聊的内容" maxlength="200" required style="width: 60%; "></textarea>
            <button class="btn btn-default" id="btnSend" style="margin-top:15px">发 送</button>
        </div>
    </div>
</body>
</html>

<script>

    var tool = function () {

        var paperLoopNum = 0;
        var paperTempleArr = [
            '<div class="list-group-item list-group-item-success">{0}</div>','<div class="list-group-item list-group-item-info">{0}</div>','<div class="list-group-item list-group-item-warning">{0}</div>','<div class="list-group-item list-group-item-danger">{0}</div>'
        ];

        return {

            paperDiv: function (val) {

                var hl = paperTempleArr[paperLoopNum];
                paperLoopNum++;
                if (paperLoopNum >= paperTempleArr.length) { paperLoopNum = 0; }

                return this.formart(hl,[val])
            },formart: function (str,arrVal) {

                for (var i = 0; i < arrVal.length; i++) {
                    str = str.replace("{" + i + "}",arrVal[i]);
                }
                return str;
            }
        }
    }

    function showMsg(id,hl,isAppend) {

        if (!isAppend) { $("#" + id).html(hl); } else {
            $("#" + id).append(hl);
        }
    }

    $(function () {

        //初始化工具方法
        var tl = new tool();

        var wsUrl = "ws://127.0.0.1:8080/webSocket";
        ws = new WebSocket(wsUrl);

        try {

            ws.onopen = function () {

                //showMsg("divShow",tl.paperDiv("连接服务器-成功"));
            }

            ws.onclose = function () {
                if (ws) {
                    ws.close();
                    ws = null;
                }
                showMsg("divShow",tl.paperDiv("连接服务器-关闭"),true);
            }

            ws.onmessage = function (result) {

                //console.log(result.data);
                var data = JSON.parse(result.data);
                $(data.UserMsgs).each(function (i,item) {
                    showMsg("divShow",tl.paperDiv("【" + item.UserName + "】:" + item.Msg),true);
                });

                var userDataShow = [];
                $(data.UserDatas).each(function (i,item) {

                    userDataShow.push('<div class="btn btn-default">' + item.UserName + '</div>');

                });
                showMsg("divUsers",userDataShow.join(''),false);
            }

            ws.onerror = function () {
                if (ws) {
                    ws.close();
                    ws = null;
                }
                showMsg("divShow",true);
            }

        } catch (e) {

            alert(e.message);
        }
        $("#btnSend").on("click",function () {

            var tContentObj = $("#txtContent");
            var tContent = $.trim( tContentObj.val()).replace("/[\n]/g","");
            var tUserName = $.trim( $("#txtUserName").val()); tUserName = tUserName.length <= 0 ? "匿名" : tUserName;
            if (tContent.length <= 0 || $.trim(tContent).length <= 0) { alert("请输入发送内容!"); return; }
            if (ws == null) { alert("连接失败,请F5刷新页面!"); return; }

            var request = tl.formart('{"UserName": "{0}","DataType": "{1}","Msg": "{2}" }',[tUserName,"send",tContent]);
            ws.send(request);
            tContentObj.val("");
            tContentObj.val($.trim(tContentObj.val()).replace("/[\n]/g",""));
        });
        $("#txtContent").on("keydown",function (event) {

            if (event.keyCode == 13) {

                $("#btnSend").trigger("click");
            }
        });
    })

</script>

效果图:

  

下载附件

原文链接:https://www.f2er.com/go/189395.html

猜你在找的Go相关文章