基于JavaFX的聊天室设计(两种后端实现:workerman和Java TCP socket)


项目地址:https://github.com/Laity000/ChatRoom-JavaFX

主要的版本控制:

  • V1.0:(2017-5-17)
  • V1.1.0:(2017-5-31) 支持emoji,改进消息气泡,优化stage控制器及其基类。
  • V1.2.1:(2018-3-13)增加workerman服务端,更新UI使客户端支持两种协议(服务端)的选择

一、写在前面

因为项目需要做一个可以跨平台远程通信的物联网设备。指令的转发跟IM的形式差不多。所以搭个聊天室,便于对以后项目的扩展。

二、功能与特性

Done & To-Do

  • 基于TCP的socket通信——>基于WebSocket的通信
  • java编写实现本地后端——>基于workerman的远程后端服务器
  • 使用Gson封装通信消息,便于扩展
  • 实现对javafx的stage控制器,并自定义stage基类
  • 支持动态更新在线用户列表
  • 支持私聊和群聊,通过用户列表切换
  • 支持显示用户头像(固定/上传
  • 支持Emoji表情,实现Emoji选择器
  • 支持图片或文件传输

三、我是图片的搬运工

这里写图片描述

  • LoginUI

这里写图片描述

  • ChatUI

这里写图片描述

  • EmojiSelectorUI

四、通信方式

通讯方式是服务端和客户端的桥梁。其设计需要服务端和客服端共同定义和兼顾。

如果只是搭建网站,当前主流的就是http 协议,用nginx+php-fpm搭建一个webserver就好了(也可以使用其他语言)。php框架可以采用thinkphp、 Laravel 、yii等等。数据格式可以使用json。请求数据的方式(API接口)可以用restful。但是客户端需要与服务器通讯的时候是单向的,必须先向服务端get/post一个请求,服务器再发送json数据。

但是因为是即时通讯,也就是需要客户端与服务端保持TCP长连接,服务端需要随时向客户端推送数据。这样便能做到客户端-服务端-客户端的及时通讯。这需要php能维持很多客户端的连接,并且需要多进程支持,以及自己的通讯协议。 传统的php框架是做不到的。国内有一款非常优秀好用的长连接PHP socket 服务器框架——workweman。

workerman是一个高性能的PHP socket 服务器框架,workerman基于PHP多进程以及libevent事件轮询库,PHP开发者只要实现一两个接口,便可以开发出自己的网络应用,例如Rpc服务、聊天室服务器、手机游戏服务器等。

GatewayWorker基于Workerman开发的一个项目框架,用于快速开发TCP长连接应用,例如app推送服务端、即时IM服务端、游戏服务端、物联网、智能家居等等

至于通信协议,http、websocket都可以。首先http适用范围非常广泛,任何平台任何语言都有现成的解析库。而websocket就是为长连接而生的,应用范围也非常广。当然也可以考虑自定义通信协议,比如在下位机中对数据的解析,不能用纯TCP传输层协议防止粘包现象。

  • 第一版设计的是本地服务器,使用java编写socket简单粗暴。于是基于TCP设计了多线程通信。
  • 后期第二版服务端考虑使用GatewayWorker框架。所有可以用websocket应用层的协议通信。

五、通信消息格式设计

通信消息(指令)是聊天的基石。如何定义好的通信消息呢?

——>首先定义是消息的类型。根据通信的方向分为两大类:

1、MessageType

  • 客户端——>服务端:
    • 用户请求登录,需要携带用户信息(connect
    • 用户请求注销(disconnect
    • 聊天对话,分为单人或全局(msg
    • 查询在线用户集(query
  • 服务端——>客户端:
    • 登录成功反馈,注意需要返回后面的用户集反馈(success
    • 登录失败反馈,重名等原因(fail
    • 聊天对话,对应的服务器进行单播或广播 (msg
    • 在线用户集(userlist
    • 通知(notification

——>然后是定义消息的各字段,即格式。我们POJO的定义一个消息类

2、Message

字段\类型connectdisconnectmsgqueryuserlistsuccessfailnotification
userinfo
from(user)
to(user)√/ALLALL
content(√)原因(√)原因
  • userinfo:用户个人信息类,保存用户名、用户头像。。。可扩展。
  • from和to:通过用户名,指定消息的发送方和接收方。
  • content:消息字符内容。

——>最后需要思考对消息的封装:

3、封装消息

  • 自定义字符串
  • 将消息类序列化传送
  • Json格式,消息类<——转化——>字符串

我们选择第三种,使用Gson将message对象封装成字符串传送。简单且可扩展。

——>最最后就交给传送了。


六、业务逻辑

1、客户端需要考虑的:

  • 登录:用户端连接服务器成功后需要登录验证(目前只需验证用户名是否重复)。
  • 窗口切换到聊天室对话主界面。
  • 动态更新在线用户列表,并可以直接在列表中选择聊天对象。
  • 分为私聊群聊,使用TCP开线程发送各类消息和指令。
  • 聊天消息实时更新:聊天对话框的消息气泡显示。
  • 注销:向服务器发送下线通知后断开物理连接。

2、服务器需要考虑的:

  • 消息中转:单播和广播——>需要保存各个用户的socket
  • 针对不同的消息做出响应的动作、反馈。
  • 并发性——>多线程。(水很深呀,但本地的最简单:])

七、聊天室界面设计

有了通信消息和业务逻辑,现在就是设计聊天室的gui了。移动端Android、Web端、PC端。。。其实都可以实现。不如先简单、直接做个桌面客户端吧。掐指一算,java的gui有啥?Awt(呵呵)、Swing(沉默不语)。好吧,还有JavaFX嘛。

其MVC的特性还是不错滴。。场景图stage、fxml跟Android开发相似,比较容易上手。☺

参考资料:


八、git学习笔记

写完了程序,就就结束了?太天真,当然还要把代码发出来,要不然你怎么看到!要不然我怎么装逼!所以,潜水很久,第一次使用github(很鸡冻呀)来管理代码和版本,同时也是展(学)示(习)代(装)码(逼):)。所以,需要对版本控制和git指令的学习。所有,先附上大神的学习资料:Git教程 - 廖雪峰的官方网站
http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
这里写图片描述
①工作区②暂存区③版本区

1、git指令

  • git diff //是工作区和暂存区的比较
  • git diff –cached //是暂存区和分支的比较
  • git diff HEAD是查看工作区和版本库(分支)的比较

  • git log 版本历史记录
  • git reflog 指令历史记录

2、撤回操作

这里写图片描述

对工作区的修改撤回:
git checkout – <文件名> 意思就是,就是让这个文件回到最近一次git commit或git add时的状态。(注意区别:git checkout -b <分支名dev>创建分支;git checkout <分支名dev>切换分支)

  • 一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
  • 一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。

对暂存区的修改撤回:
git reset HEAD <文件名>。此时只是撤回暂存区,若想工作区保持一致的撤回,使用git checkout – <文件名>
(与git reset –hard HEAD^区别:是将所有区回退到上一个版本)
这里写图片描述

3、远程推送

  • 要关联一个远程库,使用命令**git remote add origin
    git@server-name:path/repo-name.git**;
  • 关联后,使用命令git push -u origin master次推送master分支的所有内容;
  • github中fork和pull request给官方仓库的作用:
    这里写图片描述

4、分支管理

用带参数的git log也可以看到分支的合并情况:
git log –graph –pretty=oneline –abbrev-commit

git brand 查看所有分支信息

git merge –no-ff -m “merge with no-ff” 合并分支产生新的id,就是不删除被合并的分支id
这里写图片描述

BUG调试时或远程推送不一致时(上一个旧版和远程库不一致):
git stash 把当前工作现场“储藏”起来
git stash pop 恢复(或git stash applygit stash drop


九、Maven学习笔记

但是这里有个but,放到github上的代码不能很low吧,再怎么也要做到有排面吧(其实是方便build)。使用Java,不对,是JavaFX。感觉只有.project太low?用Maven来构建和管理项目。

——>好处(逼格):

  • 方便各种jar库的使用,编写好pom.xml文件(项目的配置文件)只需到中央仓库去下载了,妈妈再也不用担心我的各种库的调用和依赖库了(库儿子的库爸爸)。
  • 同时对项目进行管理。规范的文件结构适合我们这种强迫症。

——>引用资料:


更新1:V1.1.0:支持Emoji

如果能给聊天加上表情,是不是很fashion。我们选择Emoji表情,因为国际上已经定义好了统一的unicode格式(就等于有一样表情包了),不需要自己设计,方便实现。

要想支持Emoji表情的选择、展现和传输,我们需要考虑:

  • 如何存储emoji?emoji的各种格式:简称、unicode码,hex
  • 如何展示emoji?直接用unicode,还是转化为表情图片
  • 如何查找emoji?在消息字符串中解析分离emoji和其他文本
  • 如何传输emoji?
  • 如何实现emoji表情选择器?

预先善其事,必先利其器。我们首先查找相关的文档。

参考资料

设计概述

如果直接使用emoji的unicode码(文本形式)展示,虽然简单。但是①并不是所有的字体都支持;②没有图片表情好看。所有我们使每个emoji实体都有对应的表情图片,用图片的形式展现,但增加了处理的复杂性。

这里写图片描述


更新2:V1.2.1

  • 添加基于workerman框架的服务端。目前有两种方式的服务端:
    • java服务端:基于TCP的Text自定义协议通信
    • workerman服务端:websocket协议通信(具体框架说明及手册详见workerman官网)
  • 更新客户端UI支持两种协议(服务端)选择。运行方式:
    • java服务端:直接在IDE中运行ChatServer-TXP文件
    • workerman服务端:在ChatServer-WSP-by-wm-for-win文件夹中启动start_for_win.bat(业务逻辑在Events.php中)
    • 客户端都支持这两种协议。但由于服务端各自协议不同,需要调整到对应服务端运行的协议才能正确通信。
  • 12
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值