宝哥软件园

使用Angular、Nodejs和socket.io构建聊天室和多人聊天室

编辑:宝哥软件园 来源:互联网 时间:2021-09-08

1、使用Node构建静态服务器

这是这个项目的底层支撑部分。用于支持html、CSS、gif、jpg、png、JavaScript、JSON、纯文本等静态资源文件。存在mime类型的文件映射。

mime.js

/** * mime类型映射* @ authorchengluifeng * @ date 2014/8/30 *当请求静态服务器文件html、CSS、gif、jpg、png、JavaScript、JSON、纯文本的类型时,我们将在此文档中映射*/exports . type={ ' CSS ' : ' text/CSS ',' gif' :' image/gif ',' html' :' text/html ',' ico' :' image/x在这里,我将解释从输入网址到页面外观的过程。当用户在浏览器地址栏中输入网址时。

然后会发生一系列的过程。首先是DNS解析,将域名转换为对应的IP地址,然后浏览器和远程Web服务器通过TCP三次握手协商建立TCP/IP连接。握手包括在浏览器和服务器之间传输的同步消息、同步响应消息和响应消息。在这个握手过程中,客户端首先尝试建立通信,然后服务器应答并接受客户端的请求,最后客户端发送一条消息表明请求已被接受。一旦建立了TCP/IP连接,浏览器将通过该连接向远程服务器发送HTTP GET请求。

远程服务器找到资源,并以HTTP响应的形式返回它。值为200的HTTP响应状态表示响应正确。此时Web服务器提供资源服务,客户端开始下载资源。下载的资源包括html文件、css文件、javascript文件和图像文件。然后开始构建渲染树和DOM树,会被css和js屏蔽。所以底层需要一个静态的服务器支持。在这里,我构建了一个静态服务器,没有使用express框架。

事实上,每个资源文件请求过程都是一次又一次的GET请求。让我解释一下对应于客户端GET请求的服务器端处理过程(linux下的浏览器端或curl模式)。向服务器发送GET请求后,服务器可以根据Get请求对应一个资源文件的路径。知道了这个路径,我们就可以通过读写文件来获取指定路径下的资源,然后返回给客户端。

我们知道Node中读写文件的API包括readFile和readFileSync,但是更好的方式是通过流式读取文件。流式传输的优点是可以使用缓存和gzip压缩。

好的,那么如何实现缓存呢?通常,当客户端第一次发出请求时,服务器会读取资源文件并将其返回给客户端。但是,当您第二次请求相同的文件时,此时仍然需要向服务器发送请求。服务器将根据Http头信息(如过期、缓存控制和if-modified-after)判断该资源是否已被缓存。如果有缓存,服务器将不会再次访问资源文件的实际路径。直接返回缓存的资源。

server.js

/** * 聊天室服务端* 功能:实现了结节版的静态服务器* 实现了缓存,gzip压缩等* @作者程* @日期2014/8/30 *//设置端口号var PORT=3000//引入模块var http=require(' http ');var URL=必选(' URL ');var fs=require(' fs ');var path=require(' path ');var zlib=require(' zlib ');//引入文件var mime=require(' ./mime ').类型;var config=require(' ./config ');var chatServer=require(' ./utils/chat _ server’);var server=http.createServer(函数(req,res) { res.setHeader('Server ',' Node/V8 ');//获取文件路径var pathName=url.parse(req.url).路径名;if(pathName。切片(-1)='/'){ pathName=pathName '索引。html ';//默认取当前默认下的index.html }//安全处理(当使用Linux操作系统操作系统的卷曲命令访问时,存在安全隐患)var realPath=path.join('client ',路径。规范化(路径名。替换(/)../g,")))));//检查文件路径是否存在路径. exists(realPath,函数(存在){ //当文件不存在时的情况,输出一个404错误if(!存在){ res.writeHead(404,'未找到、{“内容类型”:“文本/纯文本”});res.write('找不到请求URL“PathNAmE”!);RES . end();} else { //当文件存在时的处理逻辑fs.stat(realPath,function(err,stat) { //获取文件扩展名var ext=路径。扩展名(真实路径);ext=ext?ext.slice(1) : "未知";var content TYPe=mime[ext]| |“text/plain”;//设置内容类型res.setHeader('内容类型,内容类型);var上次修改时间=stat。时间。tout cstring();var If Modified after=' If-Modified-after ' .toLowerCase();res.setHeader('上次修改,上次修改);if (ext.match(config .过期。文件匹配)){ var expires=new Date();过期。settimes()过期。gettimes()配置.过期。MaxAge * 1000);res.setHeader('过期,过期。tout cstring());res.setHeader('缓存控制','最大年龄='配置到期。MaxAge);} if(req。标题[如果在]上次修改后修改==请求。标题[如果在之后修改]){ RES .写标题(304,'未修改');RES . end();} else { //使用流的方式去读取文件var raw=fs。createreadstream(真实路径);var accept编码=req。标头['接受编码']| | ';var matched=ext.match(配置.压缩。匹配);如果匹配,接受编码。匹配(/ bgzip b/){ RES . write head(200,' Ok ',{ ' Content-Encoding ' : ' gzip ' });raw.pipe(zlib.createGzip()).管道(RES);} else if(匹配的接受编码。匹配(/ bdeflate b/){ RES . write head(200,' Ok ',{ ' Content-Encoding ' : ' deflate ' });raw.pipe(zlib.createDeflate()).管道(RES);} else { res.writeHead(200,' Ok ');原始管道;}//下面是普通的读取文件的方式,不推荐

//fs.readFile(realPath,'二进制',函数(err,data) {//if(err) {////file存在,但在读取//res.writeHead(500,{ ' Content-Type ' : ' text/plain ' })时出现一些错误;//RES . end(err);//} else {////文件存在,可以成功返回//res.writeHead(200,{ ' Content-Type ' : Content Type });//res.write(数据,' binary ');//RES . end();//}//});} });} });});//监听3000端口

server.listen(PORT,function() { console.log('服务器正在侦听端口端口'!');});//让socket.io服务器和超文本传送协议(超文本传输协议的缩写)服务器共享一个端口

chatServer.listen(服务器);二,服务端利用WebSocket构建聊天室服务端

为什么采用websocket?

我们知道现在主流的聊天室还是采用创建交互式、快速动态网页应用的网页开发技术去实现客户端和服务端的通信。采用的是一种轮询的机制。所谓轮询,就是客户端每隔一段时间就去发送一次请求,询问服务端,看看服务端有没有新的聊天数据,如果有新的数据,就返回给客户端。

Websocket完全不同。Websocket是基于长链接的。也就是说,一旦在客户机和服务器之间建立了链接,该链接将一直存在。这是一种全双工通信。此时的机制有点类似于发布-订阅模式。客户端会订阅一些事件,一旦服务器有了新数据,就会主动推送给客户端。

websocket采用ws协议,而不是http协议或https协议。此外,使用websocket的另一个优点是可以减少大量的数据流量。在文章的开头,我已经介绍了传统的一次性资源请求流程,该流程需要三次握手协议,并且每个请求头都占用很大的空间,这会耗费大量的流量。而Websocket中的Header非常小——只有大约2个字节。

/* * *聊天服务。*/var socket io=require(' socket . io ');var iovar guest number=1;//初始用户名号码var昵称={ };//昵称列表var name sused=[];//使用的用户名var CurrentRom={ };//当前聊天室功能分配客人姓名(套接字、客人编号、昵称、使用的姓名){var name=' guest '客人编号;昵称[socket . id]=name;socket.emit('nameResult ',{ success: true,name : name });namesUsed.push(名称);返回客人号码1;}功能joinRoom(socket,room){ socket . join(room);current oom[socket . id]=room;socket.emit('joinResult ',{ room : room });插座。广播。到(房间)。emit('message ',{ text:昵称[socket.id]'已加入' room ','});}函数handleMessageBroadcasting(socket){ socket . on(' message '),函数(message){ socket . broadcast . to(message . room)。emit('message ',{ text:昵称[socket . id]' : ' message . text });});}exports.listen=function(服务器){ io=socketio.listen(服务器);io.set('日志级别',1);//定义连接处理io.sockets.on ('connection ',function(socket){//分配用户名guestnumber=assign guest name(socket,guest number,昵称,使用的名称);//在聊天室大厅添加用户加入房间(socket,‘大堂’);//处理聊天信息的消息广播(socket,昵称);//handlenamechangetries(套接字、昵称、名称使用);//handleRoomJoining(套接字);//handleClientDisconnection(socket,昵称,name sused);});};第三,使用Angular构建一个聊天室客户端

为什么要用Angular?

作为一个前端MVC框架,Angular.js无疑是引人注目的。模块化,双向数据绑定,指令系统,依赖注入。而且Angular内置了jQuerylite,这让熟悉jquery语法的学生很容易理解。

当然,就个人而言,angular在构建单页应用程序和crud项目方面有很大的优势。我们的聊天室基于SPA(单页应用)。

index.html

!DOCTYPE html html ng-app=' Chatapp ' head meta name=' viewport ' content=' width=device-width,user-scalable=no '/head body ng-controller=' InitCtrl ' div ng-view/div script src=' http : lib/Angular . js '/script script src=' http : lib/Angular-route . js '/script script src=' http 3360 lib/socket . io . js '/script script src=' http 3366单页申请的原则?

先说说单页申请的原理。所谓单页,并不意味着整个页面没有刷新。当你查看google chrome的控制台时,你会发现angular仍然使用ajax异步请求资源。所以只是部分刷新。然而,与以往的删除和修改DOM节点相比,这种方法有了很大的进步。

为了构建一个单页应用程序,我们需要使用angular-route.js这个angular子项目可以帮助我们定义路由和相应的逻辑处理控制器。有了它,我们可以实现单页应用。

app.js

/* * *客户端(目前只支持浏览器,未来会扩展到移动终端)程序入口文件*创建模块,并命名为chatApp *配置路由实现单页应用*/var chatap=angular . module(' chatap ',[' ngRoute ']);//路由配置chatapp.config(函数($ route provider){ $ route provider . when('/',{ template URL 3360 ' view/init . html ',controller: 'InitCtrl' })。when('/init ',{ TemplateURl : ' view/init . html ',controller : ' init ctrl ' });});客户端聊天界面的代码逻辑如下

InitCtrl.js

/* * * * # InitCtrl */angular . module(' Chatapp ')。控制器(' InitCtrl ',函数($ scope){ var socket=io . connect(' http://127 . 0 . 0 . 1:3000 ');socket.on('nameResult ',function(result){ var message;if (result.success) { message='您现在被称为' result.name '。console.log('message=',message);document . getelementbyid(' guest name ')。innerHTML=消息;} else { message=result.message} });socket.on('joinResult ',function(result){ document . getelementbyid(' room ')。innerHTML=result.room});$ scope . sendmail=function(){ var message={ room : ' hall ',text : document . getelementbyid(' user _ input ')。值};socket.emit('message ',message);};socket.on('message ',function(message){ var p=document . create element(' p ');p . innerHTMl=message . text;document . getelementbyid(' message ')。append child(p);});});基于node.js和socket.io建立多人聊天室

只是学习node.js,想做点什么,练练手。网上的东西很多,所以走了很多弯路,花了一天时间调整代码。参考网上的一篇文章,重写了部分代码,最初是基于node-websocket-server的框架。我没有用框架,只是用socket.io

一.基本职能

1.用户可以随意输入昵称登录

2.成功登录后,

1)对于正在登录的用户,列出所有在线用户,并列出最近的历史聊天记录

2)对于已登录用户,通知新用户进入房间并更新在线用户列表

3.退出登录

1)支持直接退出

2)当用户退出时,所有其他在线用户将收到一条消息,通知他们退出房间,并同时更新在线用户列表

4、聊天

1)聊天即广播,向所有在线用户广播信息

5.一些错误处理

1)系统逻辑错误、网络错误等特殊情况下的错误提示只是临时处理

问题:功能不全,bug(退出后新用户重新登录,或者原用户)。花时间完善它

二、技术介绍

Socket.io(官网:http://socket.io/)是跨平台的,多种连接方式自动切换,方便开发即时通讯,可以很好的结合expressjs提供的传统请求方式,即可以提供两种连接方式:Request/Response、同域名同端口的WebSocket (FlashSocket、Ajax……)。

本文详细介绍了socket.io的使用://www . JB 51 . net/article/71361 . htm。

《用node.js和Websocket做个多人聊天室吧》 http://www . html 5 China.com/HTMl 5 features/WebSocket/20111206 _ 3096 . html

三、注意事项

(1)客户端引用socket.io.js如下:

脚本src=' http :/socket . io/socket . io . js '/脚本可能无法加载(我在这里花了很多时间)

它可以更改为:

script src=' http :http://ip 3360 port/socket . io/socket . io . js '/script(对应服务器的IP地址和端口号,如localhost和端口80)

(2)实现播出时,参考官网的写法,不工作,比如:

var io=require('socket.io ')。倾听(80);io.sockets.on('connection ',function(socket){ socket . broadcast . emit(' user connected ');socket . broadcast . JSON . send({ a : ' message ' });});我后来读到:http://stackoverflow。com/questions/7352164/update-all-clients-use-socket-io

更改为以下内容才能生效:

io.sockets.emit('users_count ',clients);第四,效果图

动词(verb的缩写)下载源代码

Nodejs多人聊天室(点击这里下载源代码)

ps:

1.在命令行上运行

然后在浏览器中打开index.html。如果浏览器(ff、Chrome)不支持,请升级到支持WebSocket的版本。

2.推荐node.js的IDE WebStorm

以上内容是基于Angular和Nodejs构建聊天室和多人聊天室的实现。希望大家喜欢。

更多资讯
游戏推荐
更多+