1 课程设计目的和任务

本项目的是实现在web应用上进行多人聊天,为以后在大型项目中实现客服在线服务做一个测试,提前了解HTML5新特性,熟练掌握websocket技术。

2 课程设计的主要内容

  1. 实现图形界面
  2. 实现一个聊天室中多人聊天
  3. 实现发送图片和表情的功能

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 需求分析

  1. 目前网站所提供的服务已经越来越难满足客户的需要,客户需要和提供网站服务的公司产生直接的联系,目前越来越多的网站都需要提供在线客服服务,用来满足客户的需求。
  2. 本项目就是为了能够实现在web应用中,实现实时聊天技术,并且网上很多的客服聊天都没有实现消息记录的功能,本项目能够提供消息记录的存储,使得客户端和服务端都能记录自己的聊天信息。

5 概要设计

5.1 前端接口设计
1.登录:提供一个登录功能,用户要加入聊天室需要提供用户名和头像,方便后端识别客户端信息。登录成功则实现跳转到聊天主界面。
2.主界面:需要提供用户列表,在线聊天人数,广播用户离开和加入消息,实现实时通信,及时获取聊天信息,可以发送文字、图片和表情等。实现自己的消息和别人的消息在不同的地方显示,方便识别,别人的消息要显示用户名和头像,自己的消息只显示头像
5.2 后端接口设计
1.登录:接收用户提供的用户名和头像信息,并且判断该用户是否登录,空白名字不允许登录,返回登录成功和失败的信息。
2.后端作为消息的中转站,负责广播转发,或者私发。并且将用户的信息和聊天记录存入数据库。
3.老用户登录则将他之前的聊天记录转发给他,新用户则看不到聊天记录,并将新用户的信息存入数据库。
4.服务端实时监测用户的登录状态,用户退出或断开连接,将用户退出的消息广播给所有用户
5.告诉客户端目前的用户列表和在线人数,使客户端实时更新用户列表和在线人数

5.3 数据结构设计
1.用户:用户有用户名、用户头像,在聊天系统中不提供用户ID,将用用户名区分不同的用户。
2.聊天消息:使用用户名区分不同的聊天消息,聊天信息中包含用户名、用户头像和聊天信息。
3.图片信息:图片信息中包含用户名、用户头像和图片信息。

6 系统总体架构和数据库设计

6.1 系统的总体架构

  1. 使用Node.js创建app.js容器,用来处理客户端,为客户端提供服务
  2. Index.html作为前端,显示聊天主界面,index.js用来接收服务端的数据和将数据发送给服务端,对数据进行处理并展示在index.html页面上。idex.js还负责处理登录界面和聊天界面的转换。

6.2 数据库设计

1.本项目中使用mysql数据库。

聊天室java实现 javaweb实现聊天室_javascript


聊天室java实现 javaweb实现聊天室_聊天室java实现_02

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代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<style type="text/css">
    #div{
        /*1px : 宽度   solid: 边框为实线    red: 红色*/
        border: 1px solid red;
        width: 300px;
        height: 100px;
    }
</style>
</head>
<body>
<div id='div'></div>
<script src="/socket.io/socket.io.js"></script>
<script>
    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: '服务器你好' });
    });
</script>
</body>
</html>

测试结果:在电脑中找到项目的主目录,使用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的结果;结果输出应为2
connection.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文件,也可以在前端通过点击下载链接,从服务端拿到下载的地址,然后在保存到电脑本地,但是出于安全考虑,本身js是不能够直接访问本地资源的,所以会出现很多的问题,在发送方面也存在一些问题,我已经在寻找解决的办法,过些时间应该可以达到传输文件的目的。