关于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. phpcms输出logo下拉实例

    {pc:content action=" siteid="$siteid" order="listorder ASC"} {loop $data $k ...

  2. Oracle管理监控之段空间利用监控-oracle性能优化

    SELECT S.OWNER,       S.SEGMENT_NAME,       S.SEGMENT_TYPE,       S.PARTITION_NAME,       ROUND(BYTE ...

  3. Python爬虫框架Scrapy实例(一)

    目标任务:爬取腾讯社招信息,需要爬取的内容为:职位名称,职位的详情链接,职位类别,招聘人数,工作地点,发布时间. 一.创建Scrapy项目 scrapy startproject Tencent 命令 ...

  4. Hotel---poj3667(线段树区间问题)

    题目链接:http://poj.org/problem?id=3667 题意:酒店有n个房间,现有m个团队,每个团队需要连续 d 个房间,现在有两个操作,1:需要 d 个房间,2:从 x 开始连续 d ...

  5. 0702-spring cloud config-git仓库配置、用户授权

    一.概述 参看地址:https://cloud.spring.io/spring-cloud-static/Edgware.SR3/single/spring-cloud.html#_environm ...

  6. [RGEOS]空间拓扑关系

    -1.判断两个线段是否平行 inline bool parallel_seg_seg(Segment_2 S1, Segment_2 S2) { Vector_2 u(S1); Vector_2 v( ...

  7. Mac Atom的PHP插件

    首先,需要在 ~/.atom目录下创建 .atom文件,写入如下内容: strict-ssl = false http_proxy = socks5://127.0.0.1:16888 https_p ...

  8. python16_day37【爬虫2】

    一.异步非阻塞 1.自定义异步非阻塞 import socket import select class Request(object): def __init__(self,sock,func,ur ...

  9. The adidas NMD Singapore is one of the brands top selling

    Like pointed out, we've two adidas NMD Singapore releases using the first arriving Blue and Black as ...

  10. react 修改循环列表的当前单个子项状态:思路 拿原始state数据更改,再做请求

    handleLike(item,index){ var id = item.id; _ENV.post( _ENV.HOST+'/communion/video-up', {'user_id':loc ...