zoukankan      html  css  js  c++  java
  • node+websocket创建简易聊天室

    关于websocket的介绍太多,在这就不一一介绍了,本文主要实现通过websocket创建一个简易聊天室,就是90年代那种聊天室

    服务端

    1.安装ws模块,uuid模块,ws是websocket模块,uuid是为了生成唯一id的模块

    2.创建socketServer.js,引入相应模块

    let ws = require('ws');            //引入websocket模块
    let uuid = require('uuid');        //引入创建唯一id模块

    3.创建socket服务,创建客户端连接数组

    let socketServer = ws.Server;
    
    let wss = new socketServer({port: 8090});    //创建websocketServer实例监听8090端口
    
    let clients = [];                //创建客户端列表,用于保存客户端及相关连接信息

    4.创建广播方法,用于向所有客户端推送消息

    /**
     * 广播所有客户端消息
     * @param  {String} type     广播方式(admin为系统消息,user为用户消息)
     * @param  {String} message  消息
     * @param  {String} nickname 用户昵称,广播方式为admin时可以不存在
     */
    function broadcastSend(type, message, nickname) {
        clients.forEach(function(v, i) {
            if(v.ws.readyState === ws.OPEN) {
                v.ws.send(JSON.stringify({
                    "type": type,
                    "nickname": nickname,
                    "message": message
                }));
            }
        })
    }

    5.开始监听端口以及数据

    //监听连接
    wss.on('connection', function(ws) {
        let client_uuid = uuid.v4();
        let nickname = `AnonymousUser${clientIndex++}`;
        clients.push({
            "id": client_uuid,
            "ws": ws,
            "nickname": nickname
        });
    
        console.log(`client ${client_uuid} connected`);
        /**
         * 关闭服务,从客户端监听列表删除
         */
        function closeSocket() {
            for(let i = 0; i < clients.length; i++) {
              if(clients[i].id == client_uuid) {
                let disconnect_message = `${nickname} has disconnected`;
                broadcastSend("notification", disconnect_message, nickname);
                clients.splice(i, 1);
              }
            }
        }
        /*监听消息*/
        ws.on('message', function(message) {
            if(message.indexOf('/nick') === 0) {
                let nickname_array = message.split(' ');
                if(nickname_array.length >= 2) {
                    let old_nickname = nickname;
                    nickname = nickname_array[1];
                    let nickname_message = `Client ${old_nickname} change to ${nickname}`;
                    broadcastSend("nick_update", nickname_message, nickname);
                }
            } else {
                broadcastSend("message", message, nickname);
            }
        });
        /*监听断开连接*/
        ws.on('close', function() {
            closeSocket();
        })
    })

    客户端

    html:

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
        <style>
            p {
                color: orange;
                padding: 5px 10px;
                margin: 0;
            }
            .user_msg {
                color: #ccc;
            }
            #messages {
                background: #000;
            }
        </style>
        <div class="vertical-center">
            <div class="container">
                <ul id="messages" class="list-unstyled"></ul>
                <hr/>
                <form role="form" id="chat_form" onsubmit="sendMessage(); return false;">
                    <div class="form-group">
                        <input class="form-control" type="text" id="message" name="message"
                               placeholder="Type text to echo in here" value="" autofocus/>
                    </div>
                    <button type="button" id="send" class="btn btn-primary"
                            onclick="sendMessage();">
                        Send Message
                    </button>
    
                </form>
                <div class="form-group"><span>nikename:</span><input id="name" type="text" /> <button class="btn btn-sm btn-info" onclick="changName();">change</button></div>
            </div>
        </div>

    js:

        //建立连接
            var ws = new WebSocket("ws://localhost:8090");
            var nickname = "";
            ws.onopen = function (e) {
                console.log('Connection to server opened');
            }
            //显示消息
            function appendLog(type, nickname, message) {
                if (typeof message == "undefined") return;
                var messages = document.getElementById('messages');
                var messageElem = document.createElement("li");
                var preface_label;
                var message_text;
                if (type === 'notification') {
                    preface_label = `<span class="label label-warning"><i class="glyphicon glyphicon-plus"></i></span>`;
                    message_text = `<p>${preface_label}&nbsp;&nbsp;${message}</p>`
                } else if (type == 'nick_update') {
                    preface_label = `<span class="label label-warning"><i class="glyphicon glyphicon-bullhorn"></i></span>`;
                    message_text = `<p>${preface_label}&nbsp;&nbsp;${message}</p>`
                } else {
                    preface_label = `<span class="label label-info">${nickname}</span>`;
                    message_text = `<p class="user_msg">${preface_label}&nbsp;&nbsp;${message}</p>`
                }
                messageElem.innerHTML = message_text;
                messages.appendChild(messageElem);
            }
            //收到消息处理
            ws.onmessage = function (e) {
                var data = JSON.parse(e.data);
                nickname = data.nickname;
                appendLog(data.type, data.nickname, data.message);
                console.log("ID: [%s] = %s", data.id, data.message);
            }
            //监听连接关闭情况
            ws.onclose = function (e) {
                appendLog("Connection closed");
                console.log("Connection closed");
            }
            //发送消息
            function sendMessage() {
                var messageField = document.getElementById('message');
                if (ws.readyState === WebSocket.OPEN) {
                    ws.send(messageField.value);
                }
                messageField.value = '';
                messageField.focus();
            }
            //修改名称
            function changName() {
                var name = $("#name").val();
                if (ws.readyState === WebSocket.OPEN) {
                    ws.send("/nick " + name);
                }
            }

    此时,我们的聊天室就已经完成了

    websocket最主要的问题在于没有内置的分组功能和广播功能,需要程序员自己实现,理论上来说,构建好合适的分组结构,完全可以在网页上实现qq的功能

  • 相关阅读:
    排序算法【java实现】(二)冒泡排序和简单选择排序
    排序算法【java实现】(一)直接插入排序
    Html中行内元素和块级元素有哪些?
    设计模式--单例模式(二)双重校验锁模式
    设计模式--单例模式(一)懒汉式和饿汉式
    给定一个字符串数组{"nba","abc","cba","zz","qq","haha"},请按照字典顺序进行从小到大的排序。
    请统计"nba"在字符串"nbaernbatynbauinbaopnba"中出现的次数
    java string方法
    css中的颜色值
    jquery动画效果中,避免持续反应用户的连续点击
  • 原文地址:https://www.cnblogs.com/timmer/p/6520628.html
Copyright © 2011-2022 走看看