java大作业设计报告JAVA聊天室文档格式.docx
- 文档编号:8658800
- 上传时间:2023-05-12
- 格式:DOCX
- 页数:22
- 大小:328.10KB
java大作业设计报告JAVA聊天室文档格式.docx
《java大作业设计报告JAVA聊天室文档格式.docx》由会员分享,可在线阅读,更多相关《java大作业设计报告JAVA聊天室文档格式.docx(22页珍藏版)》请在冰点文库上搜索。
为提高效率,采用多线程结合线程池设计技术,对于每个请求在线程池内得到一个线程去处理请求。
如图3-1所示。
客户端设计
5
图41服务器概要图
聊天室中一个事物的过程基本流程是:
用户产生动作,客户端发送消息,服务器接收并处理,服务器返回处理结果,GUI根据结果进行显示的更新。
客户端只在GUI中采用多线程设计。
而对服务器回应的接受都是单线程的因为只有一个服务器为自己服务,且在接收数据过程中连接是不可断开的。
客户端的设计如图3-2所示。
一次事物流程中的步骤编号在图中给出。
4
3
&
7
6
1
2
图42客户端概要图
6详细设计
服务器详细设计
服务器要完成的任务是接受客户请求并在自己维护的数据结构上进行相应处理最终将处理结果返回给客户端。
具体涉及到多线程,数据库,网络通信几项技术,同时为了实时根据请求产生特定类的对象使用了反例技术。
6.1.1<
6.1.2总体概览
服务器端的入口类为ServerMain。
聊天室服务器端代码可分为以下八个部分。
除最后两个部分外其他部分为串行执行。
在接听后,创建的线程会并发处理客户请求。
由于各个处理并发的特点,使得服务器的响应不会应为某个而用户阻塞,提高了效率。
图51聊天室服务器代码布局
服务器将用户操作抽象为不同的工作类,在接收到请求后根据消息协议在当前实现的工作类名列表中找到类名(通过下标在CommandList类中的List<
String>
commandsList属性中得到),通过反例技术直接生成类的对象。
各个类对象负责具体工作,他们都继承ServerWorkClass。
而ServerWorkClass继承自WorlClass因为客户端对服务器的回复也应当有特定的类去处理它。
目前实现的类有以下五种。
当要添加新功能时只需向commandsList属性静态添加索引。
进一步,也可在以后加入新的机制实现动态添加功能。
表52工作类名及其工作内容
!
类名
服务器端动作
HouseRelative
处理用户的进入、离开房间请求
Login
处理用户的上线、下线请求
Messages
处理用户的消息发送请求
$
UserDelAdd
处理用户注册请求
UserInfo
处理用户的用户信息查询设置请求
服务器中涉及到的类图如下所示:
6.1.3协议约定及实现
由于要考虑客户端的各个请求需要完成不同的操作,需要根据数据来内容来做特定的工作,本聊天室将通信协议定义如下:
】
userID:
服务器通过此ID确定消息是由哪个用户发出的。
authorizationcode:
服务器对用户身份进行认证的域,每次在接受用户请求后都会更新一个随机数,并且将内容返回,而用户在请求服务器时必须使用最新的验证码否则不会得到服务器响应。
这防止了非法用户的不正当操作。
command:
表示用户的请求类型其值为具体操作的工作类在commandsList中的下标,服务器通过此下标找到类名产生类的对象。
到这里为止的工作都是由一个CommandHandler的类的对象来完成,它实现了Runnable接口,在Accepter类的对象接受到消息后产生一个线程来执行对消息的下一步处理,其主要工作就是通过WorkingClassFactory使用反例技术产生具体工作类,之后调用工作类的doJob()方法完成任务。
command2:
一个具体工作类是对一类操作的抽象,如与房间相关的操作可能包括进房间和出房间,而具体内容就是根据command2来标示的。
从这里开始的工作已经进入到了WorkingClass的代码区域。
result:
是服务器向客户端告知请求是否正常完成的字段。
之后就是具体消息的定义区域。
首先一个MessageAmount来表示消息个数,而之后每条消息都有一个int域来表示其长度。
为了支持中文,采用字符数组而不是字节数组。
服务器和客户端都将协议下的具体报文封装在了PacketUnit类中,其主要提供了一个通过输入流来构建自身的构造方法和重写了toString方法以便发送时序列化。
《
PacketUnit的产生源头是GUI的监听处理函数。
由特定部位按钮或组件调用PackUnitGenerator类的特定静态方法产生特定的对象。
6.1.4初始化数据库
数据库采用JAVA数据库JDBC技术。
一般步骤为加载特定数据库驱动,产生建立连接的URL,根据URL连接数据库,在连接上创建statement类的对象进行查询和更新任务的发送。
与数据库有关的所有工作都由DataBaseServer类来完成。
由于考虑到聊天室中大部分操作不需要数据库,并且全程一个连接可能在并发过程中会导致潜在的错误,在初始化中只进行了驱动的加载。
之后需要查询或更新数据库时通过创建DataBaseServer类的对象来创建新的连接,以对象为单位向数据库发送查询请求。
DataBaseServer主要提供以下几个方法:
publicstaticvoidinit();
完成数据库驱动的加载,并且由于静态方法第一次调用,获取服务器连接的DataBaseServer静态属性URL也会在此时生成。
publicDataBaseServer();
DataBaseServer的构造函数,每次调用都会创建一条向MYSQL数据库的连接。
|
publicintupdateQuery(Stringjob);
向已连接的数据库发送一个更新请求,参数为SQL更新语句。
publicResultSetgetResult(Stringjob);
向已连接的数据库发送一个查询请求,参数为SQL查询语句。
并且返回一个ResultSet结果,是一个包含了查询结果的对象。
具体代码位于文件内。
数据库采用MySQL数据库,使用到了两张表,定义如下:
userinfo表:
"
表项
类型
uid
int
name
varchar
password
@
gender
char
telearea
telephone
nickname
!
birthyear
birthmonth
birthday
homeland
·
info
houseinfo表:
hid
^
shid
housename
ouid
createyear
)
createmonth
createday
houseinfo
varbinary
6.1.5]
6.1.6初始化用户信息
用户信息不仅是服务器对客户端的抽象,也是服务器内部对用户进行管理最基本的类。
在服务器中以User类来表示用户。
其有用户的基本个人信息,以及用户所在客户端的IP和端口(在Login过程后初始化),和用户当前所在房间的列表(以便用户名等信息更新时及时通知所有看得到此用户的用户)。
属性:
homeLand:
String
~
uid:
int
info:
userName:
authCode:
password:
*
ipAddress:
InetAddress
gender:
char
port:
telearea:
ipAddressEvil:
telephone:
;
portEvil:
nickname:
currentHouse:
List<
House>
birthYear:
ownHouse:
]
birthMonth:
birthDay:
总体上,服务器在初始化时从数据库中直接读取所有用户,并且将他们存储于线下用户的userAll表中(这里有一个基本约定:
服务器启动时是没有用户在线的),而在线用户则存储在另一个userCul表中,这两个表在服务器中表示了当前的所有用户的集合。
而这两个表的维护归一个叫做UserFactory的类来管理,它负责向外界提供User对象采用了工厂设计模式,并且采用了单例模式,因为一个服务器只需一个工厂进行管理。
用户初始化的流程如下:
;
UserFactory对外提供如下几个方法:
publicUsergetByUid(intuid);
通过用户编号获得User类的对象。
publicUsergetByName(Stringname);
通过用户名获得User类的对象。
publicUsercreateUser(String[]messages);
创建一个用户并且将其写入数据库,同时存入userAll。
publicUserupdateUser(String[]messages,UseruserTmp);
更新一个用户的信息,将其写入到数据库中。
用户名改变造成的客户端与服务器不一致由UserInfo类处理,一般情况下此方法也只由UserInfo类的对象调用。
publicvoidloginAUser(Userutm);
使一个用户由线下状态转换为线上状态。
即从userAll表转移到userCul表。
publicvoidlogoffAUser(Userutm);
与loginAUser相反。
publicbooleanisOnline(intuid);
检查一个用户是否在线。
publicbooleanisExists(intuid);
通过UID检查指定用户是否存在。
publicbooleanisExists(StringcheckName);
通过用户名检查指定用户是否存在。
publicList<
User>
getUserCur();
获取所有在线用户。
具体代码位于内。
6.1.7初始化房间信息
房间是用户间通信的场所,通信不可能从一个房间到另一个房间。
在服务器中房间用House类表示。
为此,房间主要维护一个房间内用户的表,以便某个用户发送消息时使服务器知道该把消息发送给谁。
房间信息的初始化类比用户信息的初始化,也使用了工厂模式和单例技术,只是少了在线不在线这个概念。
House的工厂类为HouseFactory。
其向外提供了通过HID或房间名来获取房间对象的方法。
不再赘述。
6.1.8设置本地发送端的Socket
为了实现异步通信,在通信过程中客户端和服务器总共需要四个Socket,分别用于服务器接受,服务器发送,客户端接受,客户端发送。
必须先设置发送端的信息,后设置接受端的信息以防止接收到请求处理完而无法发送导致的数据不一致问题。
服务器在这里设置设置服务器发送端的Socket。
通过ServerMain类调用()来实现。
而服务器发送的任务完全交给Sender类。
它主要提供一个send方法,参数是报文信息和用户,通过将报文信息字节化,获取用户的接受Socket得到发送地址和发送内容,从而执行发送过程。
6.1.9监听
监听的工作由Accepter类完成,它实现Runnable接口,在ServerMain准备好了所有内部数据后会调用方法来设置Accepter监听的本地端口,并且启用一个新线程来监听。
Accepter的run方法内创建了一个线程池,从此进入一个无限循环,内部工作为监听端口,获取输入流,产生PacketUnit,产生一个Commandhandler并包装为Thread对象后开启新的线程。
6.1.10事物处理
事务处理由WorkingClass的几个子类具体执行。
WorkingClass有一个PacketUnit类的属性因为WorkingClass的工作是围绕接收到的数据展开的,所有WorkingClass子类都应该有此成员,此成员在CommandHandler类内部产生WorkingClass时将其赋值。
ServerWorkingClass的子类都处于服务器内,主要工作就是根据请求改变服务器数据结构属于整个流程中的第四步(见图xxx)。
有一个属性UsermyUser,用于告知服务器现在服务的用户以便对服务器维护的数据进行更新。
ClientWorkingClass的子类都处于客户端内,工作是根据服务器的反馈告诉GUI做适当的显示。
负责整个流程中的第七步。
.
各子类的工作逻辑详见代码。
这里简单列出流程图。
Login:
协议:
流程:
注意:
由于第一次登陆是客户端无法知道UID所以myUser属性只能通过消息中的用户名获得。
返回消息时会设置登陆成功的客户UID由客户端维持。
HouseRelative:
、
getInHouse:
LeaveHouse:
Messages:
客户端详细设计
6.1.11总体概览
客户端主要运用到了GUI和网络通信技术。
涉及到的类之间的关系如下:
客户端执行任务的基本流程如下:
6.1.12登录界面
Login按钮的监听器会调用PackUnitGenerator来产生一个登录请求的数据包,内容见登陆部分。
之后除了接收线程还在等待服务器回复外不再进行任何动作。
接受到回复后会根据消息产生相应的界面。
只有当能够登录时Next按钮才能点击,点击后,服务器就会登录此用户。
同时这个Next的监听器还会产生一条进入房间Hall的请求,从而保证了每个用户在登录成功后会进入Hall房间。
而其他房间需要用户手动进入。
6.1.13注册界面
如上图所示。
Submit按钮会检查输入是否合法,否则会提示相应输入信息的错误情况,Cancel会销毁这个对话框,如图。
若输入合法会根据输入产生一个注册的数据包发往服务器。
但还会遇到如用户名已存在的情况。
这是注册也是失败的。
6.1.14主界面
主界面上所有按钮功能均已实现。
由于需要支持多房间,在消息显示区域上方有一个EnteredHouse下拉菜单,里面每一项对应着一个消息显示区域和右下方的一个CurrentUser列表。
分别是当前房间的消息和当前房间内的用户。
右上方的AllHouse列表中的每一项代表一个房间,双击它。
若已进入房间则只是更改EnteredHouse下拉菜单的当前选择项。
若没有进入过该房间则会产生一个进入该房间的请求。
等到服务器返回消息后由HouseRelative工作类在EnteredHouse下拉菜单中创建一个条目,同时创建一个该房间的消息显示区域以及当前房间内用户的列表。
这些消息都能够从服务器返回的消息中得到。
6.1.15用户消息显示界面
在聊天室中所有用户都可以查看自己或者别人的资料,并且对自己的资料有更改权。
只需点击MyDetail按钮或者双击CurrentUser列表中的用户名即可查看消息。
7测试
加入房间,离开房间均能在其他客户端正常显示。
消息中英文发送显示正常,所有同房间内的人都能收到。
用户信息显示正确工作。
见节。
8优缺点分析
优点
1、服务器采用多线程应对客户端请求并且结合线程池技术。
使得服务器的并发量较大。
2、服务器采用将数据协议规范化,使得任务处理流程清晰。
3、服务器将对同请求产生特定的类去处理,使得各个工作之间相互分离并且使得扩展更加容易。
4、服务器将数据大部分存储在内存中减少了对数据库的访问。
5、客户端采用了接收信息对GUI进行处理的模型,使发送请求和得到响应之间异步进行从而使得交互性更好。
缺点
1、构建工作类模型及其框架的实现花费大量代码和时间。
虽然扩展性的到了提高,可是由于时间关系只能实现少数几个功能。
用户注销,好友功能,文件传输功能,私聊功能这些都是工程计划中的一部分,都需要实现。
2、GUI美观性较差。
9总结
经过一段时间的努力我们小组实现了这个简单的JAVA聊天室系。
从数据库支持下的注册用户信息更改功能,到多线程网络通信支持下的多房间多人聊天功能,到GUI支持下的交互界面,我们实现了对聊天功能的基本抽象与实现。
由于刚刚接触JAVA语言特别是GUI编程,我们的聊天室显得有些简陋,由于时间的关系我们也没有去更细心地去修改界面。
但经过这个工程的学习,我们掌握了多项JAVA编程技术。
其中的数据库,多线程,网络通信更是对我们以后的工作生涯有很大的启发和帮助。
我们现在已不仅限于只能编出一个在控制台下输入输出字符的命令行程序了。
这极大地丰富了我们的编程经历。
同时我们学到了设计需要的团队精神。
xxx同学完成了聊天室中具体技术的总结和介绍(线程池、数据库、网络通信等具体技术)。
服务器和客户端的具体工作类中与房间相关、聊天消息相关类的实现。
同时对通信做出了很大的优化,如字节数组到字符数组的迁移使得聊天室支持中文以及其他文字。
UDP到TCP的迁移解决了项目早期频发的丢包问题。
xxx同学完成了对服务器的建模、GUI的实现、以及其他工作类的实现。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 作业 设计 报告 聊天室