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 = ; 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} ${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} ${message}</p>`
} else {
preface_label = `<span class="label label-info">${nickname}</span>`;
message_text = `<p class="user_msg">${preface_label} ${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创建简易聊天室的更多相关文章
- 基于Node.js + WebSocket 的简易聊天室
代码地址如下:http://www.demodashi.com/demo/13282.html Node.js聊天室运行说明 Node.js的本质就是运行在服务端的JavaScript.Node.js ...
- node.js+websocket实现简易聊天室
(文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) websocket提供了一种全双工客户端服务器的异步通信方法,这种通信方法使用ws或者wss协议,可 ...
- php+websocket搭建简易聊天室实践
1.前言 公司游戏里面有个简单的聊天室,了解了之后才知道是node+websocket做的,想想php也来做个简单的聊天室.于是搜集各种资料看文档.找实例自己也写了个简单的聊天室. http连接分为短 ...
- 《基于Node.js实现简易聊天室系列之总结》
前前后后完成这个聊天室的Demo花了大概一个星期,当然一个星期是仅仅指编码的工作.前期的知识储备是从0到1从无到有,花费了一定的时间熟悉Node.js的基本语法以及Node.js和mongoDB之间的 ...
- 使用Html5下WebSocket搭建简易聊天室
一.Html5WebSocket介绍 WebSocket protocol 是HTML5一种新的协议(protocol).它是实现了浏览器与服务器全双工通信(full-duplex). 现在,很多网站 ...
- 《基于Node.js实现简易聊天室系列之详细设计》
一个完整的项目基本分为三个部分:前端.后台和数据库.依照软件工程的理论知识,应该依次按照以下几个步骤:需求分析.概要设计.详细设计.编码.测试等.由于缺乏相关知识的储备,导致这个Demo系列的文章层次 ...
- 《基于Node.js实现简易聊天室系列之项目前期工作》
前期工作主要包括:项目的创建,web服务器的创建和数据库的连接. 项目创建 网上关于Node.js项目的创建的教程有很多,这里不必赘述.Demo所使用的Node.js的框架是express,版本为4. ...
- 《基于Node.js实现简易聊天室系列之引言》
简述:这个聊天室是基于Node.js实现的,完成了基本的实时通信功能.在此之前,对node.js和mongodb一无所知,但是通过翻阅博客,自己动手基本达到了预期的效果.技术,不应该是闭门造车,而是学 ...
- 小案例-WebSocket实现简易聊天室
前言 在详解 HTTP系列之一讲到HTTP/2.0 突破了传统的"请求-问答模式"这一局限,实现了服务器主动向客户端传送数据.而本章将通过一种在单个TCP连接上进行全双工通信的协议 ...
随机推荐
- yii2GridView的简单使用
GridView::widget([ 'dataProvider' => $dataProvider,// 你传过来的ActiveDataProvider // 'filterModel' =& ...
- 02Del.ashx(删除班级)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using WebHelper ...
- go-002-语言结构
Go 语言的基础组成有以下几个部分: 包声明package,必须在源文件中非注释的第一行指明这个文件属于哪个包, 引入包import,在开头部位使用 import 导入包,单个包 import “fm ...
- mongodb 的使用
install: 1.ubuntu用deb安装. 2.下载压缩文件,绿色的,不用安装. 推荐此方法. 配置dbpath: 1.用deb安装的,会在 /etc 目录下 创建mongodb.conf ...
- java 多线程 day18 ThreadPoolExecutor
http://blog.csdn.net/lipc_/article/details/52025993 https://www.cnblogs.com/trust-freedom/p/6681948. ...
- C#检查文件是否被占用
第一种方法: using System.IO; using System.Runtime.InteropServices; [DllImport("kernel32.dll")] ...
- Could not load file or assembly 'Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0, ...
使用oracle数据库一个多月依赖这问题一直都得不到解决,最近任务不是很忙了,所以决定把这问题解决掉.写一篇文章做记录. 以上错误主要是net程序oracle数据库使用了Microsoft Enter ...
- VS2010/MFC编程入门之二十(常用控件:静态文本框)
上一节鸡啄米讲了颜色对话框之后,关于对话框的使用和各种通用对话框的介绍就到此为止了.从本节开始鸡啄米将讲解各种常用控件的用法.常用控件主要包括:静态文本框.编辑框.单选按钮.复选框.分组框.列表框.组 ...
- 2018 China Collegiate Programming Contest Final (CCPC-Final 2018)
Problem A. Mischievous Problem Setter 签到. #include <bits/stdc++.h> using namespace std; #defin ...
- 20145118 《Java程序设计》 第2周学习总结
20145118 <Java程序设计> 第2周学习总结 教材学习内容总结 起初翻开课本看到第三章的章节题目”基础语法”时,我就明白这是一章需要我们牢牢掌握并理解的学科.通过看课本我了解到, ...