本项目的是实现在web应用上进行多人聊天,为以后在大型项目中实现客服在线服务做一个测试,提前了解HTML5新特性,熟练掌握websocket技术。
2 课程设计的主要内容 实现图形界面实现一个聊天室中多人聊天实现发送图片和表情的功能 3 相关技术介绍1.websocket: WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。 2.websocket.io: Socket.IO是一个完全由JavaScript实现、基于Node.js、支持WebSocket的协议用于实时通信、跨平台的开源框架,它包括了客户端的JavaScript和服务器端的Node.js。 3.Node.js: Node.js是一个基于 Chrome V8 引擎的JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式 I/O 型,Node 是一个让 JavaScript 运行在服务端的开发平台,它让 JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。 4.mysql: MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),使用最常用的数据库管理语言–结构化查询语言(SQL)进行数据库管理。 5.express框架:Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。
4 需求分析 目前网站所提供的服务已经越来越难满足客户的需要,客户需要和提供网站服务的公司产生直接的联系,目前越来越多的网站都需要提供在线客服服务,用来满足客户的需求。本项目就是为了能够实现在web应用中,实现实时聊天技术,并且网上很多的客服聊天都没有实现消息记录的功能,本项目能够提供消息记录的存储,使得客户端和服务端都能记录自己的聊天信息。 5 概要设计5.1 前端接口设计 1.登录:提供一个登录功能,用户要加入聊天室需要提供用户名和头像,方便后端识别客户端信息。登录成功则实现跳转到聊天主界面。 2.主界面:需要提供用户列表,在线聊天人数,广播用户离开和加入消息,实现实时通信,及时获取聊天信息,可以发送文字、图片和表情等。实现自己的消息和别人的消息在不同的地方显示,方便识别,别人的消息要显示用户名和头像,自己的消息只显示头像 5.2 后端接口设计 1.登录:接收用户提供的用户名和头像信息,并且判断该用户是否登录,空白名字不允许登录,返回登录成功和失败的信息。 2.后端作为消息的中转站,负责广播转发,或者私发。并且将用户的信息和聊天记录存入数据库。 3.老用户登录则将他之前的聊天记录转发给他,新用户则看不到聊天记录,并将新用户的信息存入数据库。 4.服务端实时监测用户的登录状态,用户退出或断开连接,将用户退出的消息广播给所有用户 5.告诉客户端目前的用户列表和在线人数,使客户端实时更新用户列表和在线人数
5.3 数据结构设计 1.用户:用户有用户名、用户头像,在聊天系统中不提供用户ID,将用用户名区分不同的用户。 2.聊天消息:使用用户名区分不同的聊天消息,聊天信息中包含用户名、用户头像和聊天信息。 3.图片信息:图片信息中包含用户名、用户头像和图片信息。
6 系统总体架构和数据库设计6.1 系统的总体架构
使用Node.js创建app.js容器,用来处理客户端,为客户端提供服务Index.html作为前端,显示聊天主界面,index.js用来接收服务端的数据和将数据发送给服务端,对数据进行处理并展示在index.html页面上。idex.js还负责处理登录界面和聊天界面的转换。6.2 数据库设计 1.本项目中使用mysql数据库。
7 系统实现与测试7.1 安装编程环境 1.IDEA:安装IDEA2018,安装地址在微信公众号【软件安装管家】; 2.JDK:使用JDK 1.8版本以上,JDK的安装就不详述了; 3.Node.js:先在电脑上下载安装Node.js工具,这是下载地址 【http://nodejs.cn/download/】;Node.js也提供了一个下载命令npm,我们也将在后面的工程中下载相关的依赖包。 4.yarn:yarn是一种下载工具,在电脑中找到项目的主目录,使用shift+鼠标右键,打开命令行窗口(win10是Powershell),使用命令【npm install -g yarn】【npm install yarn --save】,【yarn –version】命令查看yarn的版本号,检测安装成功。 使用yarn命令安装依赖可能会出现系统不允许执行脚本的问题,下面给出解决方案:命令是windows上以管理员身份运行Powershell:执行:set-ExecutionPolicy RemoteSigned 查看执行策略:get-ExecutionPolicy;
5.socket.io:在电脑中找到项目的主目录,使用shift+鼠标右键,打开命令行窗口(win10是Powershell),使用命令 (https://socket.io/官网有详细介绍) 【yarn add socket.io】 6.express: Express 是一个保持最小规模的灵活的 Node.js Web 应用程序开发框架,为 Web 和移动应用程序提供一组强大的功能。在官网也有详细的安装说明,使用命令【yarn add express@4.15.2】安装这个框架 7.2搭建前端静态界面 由于本项目主要是学习和实现node.js的相关内容,前端界面这里就直接用网上的资源了。 7.3搭建index.js 1.index.js主要用来和node.js服务端进行通信,并将实时内容同步到前台页面显示。 7.4搭建app.js 1.app.js是服务端,是提供服务的容器,直接在项目根目录创建app.js。socket.io官网有详细的介绍,并且提供了详细的示例。 2.在官网找到express框架,利用官网提供的方法建立简单通信:在项目根目录创建index.html;下面进行项目的初始环境搭建,代码如下:app.js代码:
var app = require('express')();var server = require('http').Server(app);var io = require('socket.io')(server);//服务器开启监听3000端口;server.listen(3000,function () {console.log('服务器启动成功了哦')});//接收客户端的http请求,并返回一个index.html页面app.get('/', function (req, res) {res.sendFile(__dirname + '/index.html');});//建立连接io.on('connection', function (socket) {console.log('新用户连接了哦')//socket.emit():表示触发一个事件,可以主动给客户端发送消息;//socket.on():表示监听一个事件,监听客户端发来的消息;socket.emit('news', { hello: '你好呀,客户端' });socket.on('my other event', function (data) {console.log(data.my);});});index.html代码:
Title#div{/*1px : 宽度solid: 边框为实线red: 红色*/border: 1px solid red;width: 300px;height: 100px;}var socket = io.connect('http://localhost:3000');socket.on('news', function (data) {// console.log(data);这是控制台打印//打印到页面上document.getElementById('div').innerHTML=data.hello;socket.emit('my other event', { my: '服务器你好' });});测试结果:在电脑中找到项目的主目录,使用shift+鼠标右键,打开命令行窗口(win10是Powershell),使用命令【node ./app.js】,在客户端打开浏览器访问:
http://localhost:3000/,测试结果如下:服务器端:E:\mysocketob1> node ./app.js服务器启动成功了哦新用户连接了哦服务器你好客户端输出:客户端你好7.5正式项目开发 1.app.js:具体的代码和说明已经在项目中说得很清楚了,这里不做过多说明,关键代码太多,不能取出重要代码来详述; 2.index.js: 具体的代码和说明已经在项目中说得很清楚了,这里不做过多说明,关键代码太多,不能取出重要代码来详述,从取出聊天记录和图片,客户端连接太多会出现重复发送的问题,这里使用一个方法来改进。使用socket.off(‘事件’).on()来监听
socket.off('receiveMessagedata').on('receiveMessagedata', function (data) {console.log(data))};3.index.html: 具体的代码和说明已经在项目中说得很清楚了,这里不做过多说明,关键代码太多,不能取出重要代码来详述,存在一个bug至今没有解决,我是用div来提供输入框的,但是,在浏览器输入聊天内容时,第一个字符是输入不进去的,会自动获取到一个字母,我也不知道是什么原因; 4.数据库:采用mysql数据库(免安装版,具体使用方式,不做过多详述),使用navicat创建表(很实用很简单的数据库管理工具)。首先需要安装数据库驱动:https://www.runoob.com/nodejs/nodejs-mysql.html(菜鸟教程),使用命令【npm install mysql】,在WEB-INF中创建目录lib,将数据库驱动包复制进去,在IDEA模块中添加。数据库连接代码如下:在app.js中写入:
//创建数据库连接var mysql = require('mysql');var connection = mysql.createConnection({host: 'localhost',user: 'root',password: '',database: 'test'})//连接数据库connection.connect();//判断数据库是否连接成功,参考菜鸟教程:nodejs连接数据库;查询计算1+1的结果;结果输出应为2connection.query('SELECT 1+1 AS solution', function (error, data) {if (error) {console.log(error);console.log("数据库连接失败");} else {console.log('数据库连接成功');console.log('The solution is:', data[0].solution);}})7.6项目测试 1.后端测试结果:
PS E:\mysocketob1> node ./app.js服务器启动成功数据库连接成功The solution is: 2新用户连接了没有出现重复,可以进行插入数据--------------------------INSERT User-------------------数据插入成功----------------------------------------------------------------------------------INSERT Msg--------------------聊天记录存储成功---------------------------------------------------------张三离开了聊天室新用户连接了用户:[张三]在数据库中已经存在,不再写入数据库--------------------------SELECT Msg--------------------取到聊天记录了,我给客户端发过去咯-----------------------------------------------------------------------------------SELECT Img--------------------取到图片咯,我发过去了---------------------------------------------------------8 总结 本次项目耗时一个月,也是断断续续在做,主要是耗费在找资料的时间上面了,有时候找得心态都崩了,还好我坚持了下来,网上关于websocket这一块的资料太少也太分散,花费了大量的时间才将很多零散的资料拼接起来,虽然这个项目可以正常运行,也达到了初期的期望,但是,项目运行中会出现很多的BUG,比如说用户名输入太长没有限制,可能会导致数据库出错,websocket实现通信的方式不是很透明,导致很多的消息在他自己的缓冲区,很有可能会出现发送失败或者发送多次的情况,这种情况在做项目的过程中遇到了很多次,也没有非常好的解决办法,而且客户端与服务端通信过程中,在浏览器后台会经常报错(主要是请求超时的问题),但是我们需要一直建立着连接,才能保证实时通信,这个问题我在网上也没有看到好的解决方法;不过通过这个项目我也学到了很多的知识,比如说要学会看API文档,需要使用到什么方法,就去找相关的API去看,特别是网上相关教程资料太少的,就需要学会看API;总之,也算是了解了关于网络聊天这一块的内容,为以后在大型项目开发中也打下了基础,这篇技术文档,我也会写得很详细,为以后做项目提供基础。还有一个重要的功能没有实现,那就是文件的传输,我已经在找资料了,网上这方面的资源太少了,很多的代码也都不符合我的情况,主要是要用到处理二进制流的方式,特别是大文件传输,很容易出现问题,需要控制每次传输字节的长度,我已经试过可以传输txt文件,也可以在前端通过点击下载