zoukankan      html  css  js  c++  java
  • websocket+golang聊天室

    原文地址:

    http://www.niu12.com/article/3

    websocket+golang聊天室

    main.go和index.html放在同一目录下

    main.go

    package main

    import (
    "encoding/json"
    "fmt"
    "golang.org/x/net/websocket"
    "net/http"
    "time"
    )

    type Message struct {
    Username string
    Message string
    }

    type User struct {
    Username string
    }

    type Datas struct {
    Messages []Message
    Users []User
    }

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

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

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

    // 渲染页面
    http.HandleFunc("/", index)

    // 监听socket方法
    http.Handle("/webSocket", websocket.Handler(webSocket))

    // 监听8080端口
    http.ListenAndServe(":8889", nil)
    }

    func index(w http.ResponseWriter, r *http.Request) {
    http.ServeFile(w, r, "index.html")
    }

    func webSocket(ws *websocket.Conn) {
    var message Message
    var data string
    for {
    // 接收数据
    err := websocket.Message.Receive(ws, &data)
    if err != nil {
    // 移除出错的连接
    delete(users, ws)
    fmt.Println("连接异常")
    break
    }
    // 解析信息
    err = json.Unmarshal([]byte(data), &message)
    if err != nil {
    fmt.Println("解析数据异常")
    }

    // 添加新用户到map中,已经存在的用户不必添加
    if _, ok := users[ws]; !ok {
    users[ws] = message.Username
    // 添加用户到全局信息
    datas.Users = append(datas.Users, User{Username:message.Username})
    }
    // 添加聊天记录到全局信息
    datas.Messages = append(datas.Messages, message)


    // 通过webSocket将当前信息分发
    for key := range users{
    err := websocket.Message.Send(key, data)
    if err != nil{
    // 移除出错的连接
    delete(users, key)
    fmt.Println("发送出错: " + err.Error())
    break
    }
    }
    }
    }
    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="icon" href="./favicon.ico" type="image/x-icon" />
    <title>H5聊天室</title>
    <style type="text/css">
    .talk_con {
    100%;
    height: 100%;
    border: 1px solid #666;
    margin: 50px auto 0;
    background: #f9f9f9;
    }

    .talk_show {
    100%;
    height: 420px;
    border: 1px solid #666;
    background: #fff;
    margin: 10px auto 0;
    overflow: auto;
    }

    .talk_input {
    100%;
    }

    .talk_word {
    90%;
    height: 26px;
    float: left;
    text-indent: 10px;
    margin: 2% 5%;
    }

    .talk_sub {
    100%;
    height: 30px;
    float: left;
    }

    .atalk {
    margin: 10px;
    }

    .atalk span {
    display: inline-block;
    background: #0181cc;
    border-radius: 10px;
    color: #fff;
    padding: 5px 10px;
    }

    .btalk {
    margin: 10px;
    text-align: right;
    }

    .btalk span {
    display: inline-block;
    background: #ef8201;
    border-radius: 10px;
    color: #fff;
    padding: 5px 10px;
    }
    </style>
    <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
    <script type="text/javascript">
    $(function () {
    // 询问框获取用户昵称
    let username = localStorage.getItem("username") ?
    localStorage.getItem("username") : disp_prompt();
    let words = $("#words");
    let talkWords = $("#talkwords");
    let talkSubmit = $("#talksub");
    // webSocket
    let wsURL = "ws://chat.niu12.com/webSocket";
    ws = new WebSocket(wsURL);
    try {
    // 监听连接服务器
    ws.onopen = function () {
    console.log("已连接服务器")
    };

    // 监听关闭服务器
    ws.onclose = function () {
    if (ws) {
    ws.close();
    ws = null
    }
    console.log("关闭服务器连接")
    };

    // 监听信息
    ws.onmessage = function (result) {
    let data = JSON.parse(result.data);
    let className = "atalk";
    let user = data.username
    // 如果是本人,放在右边 不是本人 放在左边
    if (data.username === username){
    className = "btalk";
    user = "";
    }
    str = words.html() +
    '<div class=" + className + ">'+user+'<span>'
    + data.message + '</span></div>';
    words.html(str);
    var scrollHeight = words.prop("scrollHeight");
    words.scrollTop(scrollHeight);
    };

    // 监听错误
    ws.onerror = function () {
    if (ws) {
    ws.close();
    ws = null;
    }
    console.log("服务器连接失败")
    }
    } catch (e) {
    console.log(e.message)
    }

    document.onkeydown = function (event) {
    let e = event || window.event;
    if (e && e.keyCode === 13) { //回车键的键值为13
    talkSubmit.click()
    }
    };

    talkSubmit.click(function () {
    // 获取输入框内容
    let content = talkWords.val();
    if (content === "") {
    // 消息为空时弹窗
    alert("消息不能为空");
    return;
    }

    // 发送数据
    if (ws == null){
    alert("连接服务器失败,请刷新页面");
    window.location.reload();
    return
    }
    let request = {"username":username, "message":content};
    ws.send(JSON.stringify(request));
    // 清空输入框
    talkWords.val("")
    })
    });

    function disp_prompt() {
    let username = prompt("请输入昵称");
    if (username == null || username === "") {
    disp_prompt()
    }else {
    localStorage.setItem("username", username);
    return username;
    }
    }
    </script>
    </head>
    <body>
    <h1>简易聊天室</h1>
    <div class="talk_con">
    <div class="talk_show" id="words">

    </div>
    <div class="talk_input">
    <input type="text" class="talk_word" id="talkwords" placeholder="输入聊天内容">
    <input type="button" value="发送" class="talk_sub" id="talksub">
    </div>
    </div>
    </body>
    </html>
  • 相关阅读:
    js学习(六)--作用域
    js学习(五)--函数function()、for...in、函数中的方法,arguments
    js学习(四)-- 数据类型、基本数类型的包装类、js的对象、toString、构造方法、原型对象
    js自学(三)-- js的语句代码块&流程控制语句(if,while,break等)
    自学js(二)--强制类型转换&运算符(操作符)
    java的hashcode和equals
    sprinboot---读取配置文件(application.yml)中的属性值
    springboot打包为jar包后怎么在外部修改配置文件
    bat脚本编写--启动springboot服务
    关于clean报错问题 Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean (default-
  • 原文地址:https://www.cnblogs.com/zhouqi666/p/10141265.html
Copyright © 2011-2022 走看看