关于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. 170714、springboot编程之多数据源切换(动态)

    (1)新建maven java project; 新建一个maven project,取名为:spring-boot-multi-ds (2)在pom.xml添加依赖包: 在pom.xml文件中加入依 ...

  2. 转载:SQL Server编程基本语法

    一.定义变量 --简单赋值 declare @a int print @a --使用select语句赋值 ) select @user1='张三' print @user1 ) print @user ...

  3. macOS Sierra 10.12版本 显示隐藏文件

    1.显示隐藏文件 打开Terminal 输入:defaults write com.apple.finder AppleShowAllFiles -bool true 再输入: killall Fin ...

  4. 005-spring cache-配置缓存存储

    一.概述 缓存抽象提供了多种存储集成.要使用它们,需要简单地声明一个适当的CacheManager - 一个控制和管理Caches的实体,可用于检索这些实体以进行存储. 1.1.基于JDK Concu ...

  5. C#+GDAL读写文件

    读取shp文件: private void btnBrower_Click(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFil ...

  6. mac终端显示日历信息命令

    cal 命令: 用法: usage: cal [-jy] [[month] year] cal [-j] [-m month] [year] ncal [-Jjpwy] [-s country_cod ...

  7. Java之Integer源码

    1.为什么Java中1000==1000为false而100==100为true? 这是一个挺有意思的讨论话题. 如果你运行下面的代码 Integer a = 1000, b = 1000; Syst ...

  8. ZW团队:IN_OUT传播模型简介

    传统媒体,网络媒体的整合推广,我曾经提出过一个:Tn-Out模式 In-Out是NBA的篮球术语,你自己百度下 传统媒体承担"IN"的角色,负责传播的深度和建立公信力 网络媒体充当 ...

  9. 【运维技术】VM虚拟机上使用centos7安装docker启动gogs服务教程【含B站视频教程】

    VM虚拟机上使用centos7安装docker启动gogs服务视频教程 BiliBili视频教程链接飞机票,点我 使用VMware Workstation安装Centos7 MinMal系统 第一步: ...

  10. MysqL中的Show Index From Table_Name命令说明

    我们在分析SQL性能的时候,会使用到show index from table_name命令,会返回出下面的列 | Table | Non_unique | Key_name | Seq_in_ind ...