关于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 = ; i < clients.length; i++) {
if(clients[i].id == client_uuid) {
let disconnect_message = `${nickname} has disconnected`;
broadcastSend("notification", disconnect_message, nickname);
clients.splice(i, );
}
}
}
/*监听消息*/
ws.on('message', function(message) {
if(message.indexOf('/nick') === ) {
let nickname_array = message.split(' ');
if(nickname_array.length >= ) {
let old_nickname = nickname;
nickname = nickname_array[];
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的功能

node+websocket创建简易聊天室的更多相关文章

  1. 基于Node.js + WebSocket 的简易聊天室

    代码地址如下:http://www.demodashi.com/demo/13282.html Node.js聊天室运行说明 Node.js的本质就是运行在服务端的JavaScript.Node.js ...

  2. node.js+websocket实现简易聊天室

    (文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) websocket提供了一种全双工客户端服务器的异步通信方法,这种通信方法使用ws或者wss协议,可 ...

  3. php+websocket搭建简易聊天室实践

    1.前言 公司游戏里面有个简单的聊天室,了解了之后才知道是node+websocket做的,想想php也来做个简单的聊天室.于是搜集各种资料看文档.找实例自己也写了个简单的聊天室. http连接分为短 ...

  4. 《基于Node.js实现简易聊天室系列之总结》

    前前后后完成这个聊天室的Demo花了大概一个星期,当然一个星期是仅仅指编码的工作.前期的知识储备是从0到1从无到有,花费了一定的时间熟悉Node.js的基本语法以及Node.js和mongoDB之间的 ...

  5. 使用Html5下WebSocket搭建简易聊天室

    一.Html5WebSocket介绍 WebSocket protocol 是HTML5一种新的协议(protocol).它是实现了浏览器与服务器全双工通信(full-duplex). 现在,很多网站 ...

  6. 《基于Node.js实现简易聊天室系列之详细设计》

    一个完整的项目基本分为三个部分:前端.后台和数据库.依照软件工程的理论知识,应该依次按照以下几个步骤:需求分析.概要设计.详细设计.编码.测试等.由于缺乏相关知识的储备,导致这个Demo系列的文章层次 ...

  7. 《基于Node.js实现简易聊天室系列之项目前期工作》

    前期工作主要包括:项目的创建,web服务器的创建和数据库的连接. 项目创建 网上关于Node.js项目的创建的教程有很多,这里不必赘述.Demo所使用的Node.js的框架是express,版本为4. ...

  8. 《基于Node.js实现简易聊天室系列之引言》

    简述:这个聊天室是基于Node.js实现的,完成了基本的实时通信功能.在此之前,对node.js和mongodb一无所知,但是通过翻阅博客,自己动手基本达到了预期的效果.技术,不应该是闭门造车,而是学 ...

  9. 小案例-WebSocket实现简易聊天室

    前言 在详解 HTTP系列之一讲到HTTP/2.0 突破了传统的"请求-问答模式"这一局限,实现了服务器主动向客户端传送数据.而本章将通过一种在单个TCP连接上进行全双工通信的协议 ...

随机推荐

  1. WebService 的简单使用

    简单介绍 WebService是一种跨语言,跨进程,跨机器的数据交互技术. SOAP:简单对象访问协议,通过XML数据交互的轻量级协议,WebService就是采用的这种协议 WSDL:web服务描述 ...

  2. Python开发【Django】:ModelForm操作

    ModelForm 内容回顾: Model - 数据库操作 - 验证 class A(MOdel): user = email = pwd = Form class LoginForm(Form): ...

  3. Flask知识总汇

    Flask基础 Flask基础使用与配置 Flask路由系统与模板系统 Flask视图函数 Flask请求与响应 Flask的session操作 Flask中间件 Flask连接数据库 Flask使用 ...

  4. Mysql5.7.10新加用户

    INSERT INTO mysql.user(HOST,USER,authentication_string,ssl_cipher,x509_issuer,x509_subject,select_pr ...

  5. SQL Server分区键列必须是主键一部分

    SQL Server分区键列必须是主键一部分. 必须把分区列包含在主键/唯一约束/唯一索引的键列中. USE tempdb GO -- 测试表 CREATE TABLE dbo.tb( id int, ...

  6. jquery 重复导入问题

    $(...).bootstrapTable is not a function

  7. STL学习笔记--关联式容器

    关联式容器依据特定的排序准则,自动为其元素排序.缺省情况下以operator<进行比较.set multiset map multimap是一种非线性的树结构,具体的说是采用一种比较高效的特殊平 ...

  8. linux C 程序内存布局

    参考: 1. http://www.cnblogs.com/clover-toeic/p/3754433.html 2. http://www.cnblogs.com/jacksu-tencent/p ...

  9. 001-java虚拟机的概念

    https://blog.csdn.net/yfqnihao/article/details/8289363 1.什么是java虚拟机.(你以为你知道,如果你看我下面的例子,你会发现你其实不知道) ( ...

  10. ACM-ICPC 2018 沈阳赛区网络预赛 Solution

    A. Gudako and Ritsuka 留坑. B. Call of Accepted 题意:定义了一种新的运算符$x d y$ 然后给出中缀表达式,求值 思路:先中缀转后缀,然后考虑如何最大如何 ...