介绍下websocket:

webSocket协议本质上是一个基于tcp的协议;

建立一个websocket连接,大体的过程:

1.客户端浏览器首先向服务器发起一个http请求,这个请求和平常的请求有什么不同呢?

多了一点附加头信息:"upgrade:web Socket” 表明我这申请的是一个websocket的http请求;

2.服务器收到请求后,解析这些附加的头信息,然后产生应答信息返回给客户端,这样,连接就建立了;

3.双方就可以通过这个连接通道自由的信息传递,这个连接会一直存在,直到一方自动关闭连接;

客户端到服务端:

GET /demo HTTP/1.1

Host: example.com

Connection: Upgrade

Sec-WebSocket-Key2: 12998 5 Y3 1 .P00

Upgrade: WebSocket

Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5

Origin: http://example.com

[8-byte security key]

服务端到客户端:

HTTP/1.1 101 WebSocket Protocol Handshake

Upgrade: WebSocket

Connection: Upgrade

WebSocket-Origin: http://example.com

WebSocket-Location: ws://example.com/demo

[16-byte hash response]

从客户端到服务端请求的信息里面包含:‘Sec-webSocket-key1","Sec-WebSocket-key2"和“[8-byte security key]”这样的信息;这是客户端浏览器需要向服务端提供的握手信息,服务端解析这些头信息,并且在握手的过程中依据这些信息生成一个16位的安全密钥并返回给客户端,以表明服务器端获取了客户端的请求;

大致步骤:

1.	逐个字符读取 Sec-WebSocket-Key1 头信息中的值,将数值型字符连接到一起放到一个临时字符串里,同时统计所有空格的数量;
2. 将在第 1 步里生成的数字字符串转换成一个整型数字,然后除以第 1 步里统计出来的空格数量,将得到的浮点数转换成整数型;
3. 将第 2 步里生成的整型值转换为符合网络传输的网络字节数组;
4. 对 Sec-WebSocket-Key2 头信息同样进行第 1 到第 3 步的操作,得到另外一个网络字节数组;
5. 将 [8-byte security key] 和在第 3,第 4 步里生成的网络字节数组合并成一个 16 字节的数组;
6. 对第 5 步生成的字节数组使用 MD5 算法生成一个哈希值,这个哈希值就作为安全密钥返回给客户端,以表明服务器端获取了客户端的请求,同意创建 WebSocket 连接
 var  wsServer = 'ws://localhost:8888/Demo';  //连接地址
var websocket = new WebSocket(wsServer); //建立连接
websocket.onopen = function (evt) { onOpen(evt) }; //4个事件
websocket.onclose = function (evt) { onClose(evt) };
websocket.onmessage = function (evt) { onMessage(evt) };
websocket.onerror = function (evt) { onError(evt) };
function onOpen(evt) {
console.log("Connected to WebSocket server.");
}
function onClose(evt) {
console.log("Disconnected");
}
function onMessage(evt) {
console.log('Retrieved data from server: ' + evt.data);
}
function onError(evt) {
console.log('Error occured: ' + evt.data);
}

浏览器的支持情况:

浏览器	支持情况
Chrome Supported in version 4+
Firefox Supported in version 4+
Internet Explorer Supported in version 10+
Opera Supported in version 10+
Safari Supported in version 5+

正文来了:基于websocket制作的简单聊天系统;

client.html:

 <style>
.kuang {
width: 600px;
min-height: 50px;
max-height: 296px;
border: 1px solid;
float: left;
display: block;
position: relative;
overflow-y: scroll;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="jumbotron bg-dark">
<h1 class="jumbotron-heading">WebSocket chat,欢迎使用:</h1>
</div>
<div class="input-group text-left">
<label>输入用户名:</label>
<input type="text" id="name" />
<button id="conn">连接</button>
<button id="close">断开</button>
</div>
<div class="input-group text-muted">
<div class="kuang" id="mess"></div>
</div>
<hr class="featurette-divider">
<div class="input-group text-left">
<input type="text" class="value" id="value1" />
<button id="send">发送</button>
</div>
</div>
</div>

简单的界面,大致效果就是这样的:

然后实现逻辑代码:

 var ws = new WebSocket('ws://127.0.0.1:8082');
ws.onopen = function (e) {
console.log("连接服务器成功");
}
ws.onmessage = function (e) {
value1.removeAttribute("readOnly");
var time = new Date();
mess.innerHTML += time.toUTCString() + ":" + e.data + "<br>";
document.getElementById("send").onclick = function (e) {
ws.send(input.value + "说:" + value1.value);
value1.value = " ";
}
document.onkeydown = function (e) {
e = e || window.event;
if (e.keyCode == 13) {
document.getElementById("send").onclick();
return false;
}
}
}
ws.onclose = function (e) {
console.log("服务器关闭");
}
ws.onerror = function () {
console.log("连接出错");
}

连接地址:ws://127.0.0.1:8082  那是哪里来的呢?  (注意http请求则是写成http://xxx,https请求则是https://xxx;ws当然是ws://xxx);

wbsocket只是客服端,地址当然是从我们的服务端给的呀;

服务端的搭建采用了一个这样的库:

nodejs-websocket
 
1.npm isntall -g nodejs-websocket
2.在js页面引入它

var ws = require("nodejs-websocket");
3.创建一个服务

var server = ws.createServer(function (conn) {
conn.on('text', function (str) {
}) conn.on("close", function (code, reason) {
console.log("关闭连接");
})
conn.on("error", function (code, reason) {
console.log("异常关闭");
});
}).listen(8082);
console.log("websocket连接完毕")

好了,websocket连接算是建立啦!

下面展示下具体代码:

client.html

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="bootstrap-3.3.7-dist/css/bootstrap.min.css" />
<script src="jquery.min.js"></script>
<script src="bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<style>
.kuang {
width: 600px;
min-height: 50px;
max-height: 296px;
border: 1px solid;
float: left;
display: block;
position: relative;
overflow-y: scroll;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="jumbotron bg-dark">
<h1 class="jumbotron-heading">WebSocket chat,欢迎使用:</h1>
</div>
<div class="input-group text-left">
<label>输入用户名:</label>
<input type="text" id="name" />
<button id="conn">连接</button>
<button id="close">断开</button>
</div>
<div class="input-group text-muted">
<div class="kuang" id="mess"></div>
</div>
<hr class="featurette-divider">
<div class="input-group text-left">
<input type="text" class="value" id="value1" />
<button id="send">发送</button>
</div>
</div>
</div>
<script>
var input = document.getElementById("name");
var conn = document.getElementById("conn");
var close = document.getElementById("close");
var mess = document.getElementById("mess");
var value1 = document.getElementById("value1");
var pattern = /^[\u4e00-\u9fa5]{2,10}$/;
close.disabled = true;
if (window.WebSocket) {
conn.onclick = function () {
if (!pattern.test(input.value)) {
alert("名称不能为空且必须为中文");
return;
}
var ws = new WebSocket('ws://127.0.0.1:8082');
conn.disabled = true;
close.disabled = false;
ws.onopen = function (e) {
console.log("连接服务器成功");
ws.send(input.value);
input.setAttribute("readOnly", 'true');
value1.setAttribute("readOnly", 'true');
}
ws.onmessage = function (e) {
value1.removeAttribute("readOnly");
var time = new Date();
mess.innerHTML += time.toUTCString() + ":" + e.data + "<br>";
document.getElementById("send").onclick = function (e) {
ws.send(input.value + "说:" + value1.value);
value1.value = " ";
}
document.onkeydown = function (e) {
e = e || window.event;
if (e.keyCode == 13) {
document.getElementById("send").onclick();
return false;
}
}
}
ws.onclose = function (e) {
console.log("服务器关闭");
}
ws.onerror = function () {
console.log("连接出错");
} close.onclick = function () {
ws.onclose();
ws.send(input.value + 'close' + "了连接");
input.removeAttribute("readOnly");
conn.disabled = false;
close.disabled = true;
}
}
}
</script>
</body> </html>

server.js

var ws = require("nodejs-websocket");
console.log("开始建立连接...");
var str1 = null, str2 = null, clientReady = false, serverReady = false;
var a = [];
var server = ws.createServer(function (conn) {
conn.on('text', function (str) {
a.push(str);
if (!clientReady) {
if (a[0] === str) {
str1 = conn;
clientReady = true;
str1.sendText("欢迎你" + str); }
} else if (!serverReady) {
if (str.indexOf('close') >= 0) {
a.splice(2,1);
clientReady = false;
str1=null;
return;
}
if (a[1] === str) {
str2 = conn;
serverReady = true;
str2.sendText("欢迎你" + str);
str1.sendText(str + "在线啦,你们可以聊天啦");
return;
}
} else if (clientReady && serverReady) {
str2.sendText(str);
str1.sendText(str);
if (str.indexOf('close') >= 0) {
a.splice(2, a.length);
var len = a.length;
for (var i = 0; i < len; i++) {
// 定位该元素位置
if (str.indexOf(a[i])>=0) {
a.splice(i,1);
if(i==0){
str1=str2;
}
serverReady = false;
str2=null;
return;
} }
}
} }) conn.on("close", function (code, reason) {
console.log("关闭连接");
clientReady = false;
serverReady = false;
})
conn.on("error", function (code, reason) {
console.log("异常关闭");
});
}).listen(8082);
console.log("websocket连接完毕")

实现双人聊天,client.html开启两个窗口就行!

详细代码在github上:

 https://github.com/sulishibaobei/websocket-

nodejs+websocket实时聊天系统的更多相关文章

  1. WebSocket实现实时聊天系统

    WebSocket实现实时聊天系统 等闲变却故人心,却道故人心易变. 简介:前几天看了WebSocket,今天体验下它的实时聊天. 一.项目介绍 WebSocket 实时聊天系统自己一个一码的搞出来还 ...

  2. 把酒言欢话聊天,基于Vue3.0+Tornado6.1+Redis发布订阅(pubsub)模式打造异步非阻塞(aioredis)实时(websocket)通信聊天系统

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_202 "表达欲"是人类成长史上的强大"源动力",恩格斯早就直截了当地指出,处在蒙昧时代即低 ...

  3. 使用Nodejs实现实时推送MySQL数据库最新信息到客户端

    下面我们要做的就是把MySQL这边一张表数据的更新实时的推送到客户端,比如MySQL这边表的数据abc变成123了,那使用程序就会把最新的123推送到每一个连接到服务器的客户端.如果服务器的连接的客户 ...

  4. WebSocket实时异步通信

    WebSocket实时异步通信 [一]WebSocket简介 WebSocket是HTML5推出一个协议规范,用来B/S模式中服务器端和客户端之间进行实时异步通信. 众所周知,传统的HTTP协议中,服 ...

  5. Uniapp使用GoEasy实现websocket实时通讯

    Uniapp作为近来最火的移动端开发技术,一套代码,可以打包成Android/iOS app和各种平台的小程序,可谓是没有最方便只有更方便. GoEasy上架DCloud Uniapp插件市场已经有一 ...

  6. 微信小程序使用GoEasy实现websocket实时通讯

    不需要下载安装,便可以在微信好友.微信群之间快速的转发,用户只需要扫码或者在微信里点击,就可以立即运行,有着近似APP的用户体验,使得微信小程序成为全民热爱的好东西~ 同时因为微信小程序使用的是Jav ...

  7. 使用Node.js+Socket.IO搭建WebSocket实时应用

    Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新.它有着广泛的应用场景,比如在线聊天室.在线客服系统.评论系统.WebIM等. W ...

  8. python tornado websocket 实时日志展示

    一.主题:实时展示服务器端动态生成的日志文件 二.流程: 1. 客户端浏览器与服务器建立websocket 链接,服务器挂起保存链接实例,等待新内容触发返回动作 2. 日志服务器脚本循环去发现新内容, ...

  9. Nodejs websocket入门

    websocket 2011年技术文档 http://www.ibm.com/developerworks/cn/web/1112_huangxa_websocket/index.html 浏览器端接 ...

随机推荐

  1. 在IIS使用localDB

    项目使用localdb来作为本机测试数据库,发布到本机IIS后项目却链接不到数据库,查看windows日志为如下错误 "无法获取本地应用程序数据路径.很可能是因为未加载用户配置文件.如果在 ...

  2. Unity 3d游戏逆向及.NET Reflector工具使用介绍

    移动平台游戏框架主要有unity 3d和cocos 2d.我们首先得识别游戏使用的框架.识别Unity游戏Android平台的apk包可以直接解压,看是否有./assets/bin/Data/Mana ...

  3. Java异常的正确使用姿势

    最近在项目代码中,遇见异常滥用的情形,会带来什么样的后果呢? 1. 代码可读性变差,业务逻辑难以理解 异常流与业务状态流混在一起,无法从接口协议层面理解业务代码,只能深入到方法(Method)内部才能 ...

  4. 浅析python中socketserver模块使用

    虽然说用python编写简单的网络程序狠方便,但是复杂一点的网络程序还是用现成的框架比较好,这样就可以专心事物逻辑,而不是套接字的各种细节.Socketserver模块简化了编写网络服务程序,同时so ...

  5. 警惕phpstudy等开发神器使用默认配置可能带来的危险

    0x00 前言 其实这个点早在之前,我就已经想到了,当时也觉得没啥就记在了我的印象笔记里. 而今天重新把这个点拿出来讲,主要是因为今天早上在温习nmap的时候,一不小心利用这个点,拿下了一位同事的电脑 ...

  6. windows 线程

    在windows中进程只是一个容器,用于装载系统资源,它并不执行代码,它是系统资源分配的最小单元,而在进程中执行代码的是线程,线程是轻量级的进程,是代码执行的最小单位. 从系统的内核角度看,进程是一个 ...

  7. flask-信号

    flask中的十个内置信号:request_started = _signals.signal('request-started') # 请求到来前执行 request_finished = _sig ...

  8. c/s与b/s 动态网站与静态网站 (网站编码统一“UTF-8”)

    1.c/s和b/s 第一张图是b/s  可以随时随地的浏览  (在服务器增加网页就能增加功能,只要改变网页就能使用户同步更新,共享性也强,开发也简单,在广域网和局域网都能建造b/s结构,然后通过int ...

  9. HDU 2296:Ring

    Problem Description For the hope of a forever love, Steven is planning to send a ring to Jane with a ...

  10. bzoj:3085: 反质数加强版SAPGAP

    Description 先解释一下SAPGAP=Super AntiPrime, Greatest AntiPrime(真不是网络流),于是你就应该知道本题是一个关于反质数(Antiprime)的问题 ...