java 聊天室WeChat

功能和特性

  • 基于socket实现的c/s架构的的通讯
  • 服务器和客户心跳链接
  • gson实现的消息通讯机制
  • 注册及登陆
  • 支持私聊和群聊。
  • 动态更新用户列表以及用户消息提示
  • 支持emoji表情,以及emoji表情选择器
  • 服务器端数据库用户记录
  • 实现文件传输
  • 文件记录

功能展现

  • login
  • chatroom


  • 表情包
  • 数据库

总体架构

  • 使用了比较简单的worker-master架构。java

    • 由masterserve进行事件的分发
    • 由workserver具体的管理单个用户的消息请求
    • 相关模型连接 Master-Worker模式
  • 消息机制
    • 采用json做为通讯载体,后期功能性的更改较为简单
    • 通讯命令字设计以下
public final static boolean SINGLE = true;
  public final static boolean GROUP = false;
  /**
   * status
   */
  public final static int SUCCESS = 0x01;
  public final static int FAILED = 0x02;

  /**
   * message
   */
  public static Integer  COMMAND = 0x10;
  public static Integer  TIME = 0x11;
  public static Integer  USERNAME = 0x12;
  public static Integer  PASSWORD = 0x13;
  public static Integer  SPEAKER = 0x14;
  public static Integer  RECEIVER = 0x15;
  public static Integer  CONTENT= 0x16;
  /**
   * command
   */
  public final static int COM_LOGIN = 0x20;
  public final static int COM_SIGNUP = 0x21;
  public final static int COM_RESULT = 0x22;
  public final static int COM_DESCRIPTION = 0x23;
  public final static int COM_LOGOUT =0x24;
  public final static int COM_CHATWITH = 0x25;
  public final static int COM_GROUP = 0x26;
  public final static int COM_CHATALL = 0x27;
  public final static int COM_KEEP = 0x28;
  public final static int COM_MESSAGEALL = 0X29;
  • 基本响应流程概述

    • Client->Server
      • 请求注册(已注册用户请求登陆),请求登陆状态
      • 聊天命令分为单人和多人群聊
    • Server->Client
      • 返回登陆|注册成功反馈
      • 返回登陆|注册失败反馈,及失败缘由(用户已经注册|用户还没有注册|密码错误|服务器链接失败等...)
      • 每一个用户登陆广播用户集
      • 提取数据仓发送消息给指定用户
      • 广播信息
  • 心跳链接

    以前考虑上线下线方式的时候想到的一个办法是,下线的时候给服务器发送下线通知,后面考虑了出现断网等突发状况时这样的设计将出现问题。因此采用了心跳链接的方式。
    • server端采用了以时间差为判断方式的链接判断方式,经过具体的实践server端的实践差为2000ms较为合适.
    • client维持了500ms的心跳

Server

  • 启动环节
    • 服务器前先查询数据库,从中加载出用户列表到内存。android

      (注:这样的方式在数据较大时不合适,应该设计好数据库的消息存储机制,避免服务器端的数据量大时出现问题,这个小程序由于以前在设计的时候原本没有加上数据库的打算,后期加入后,也不想再次重构服务器端)ios

    • 数据库已经封装成Dao层,使用双重锁的单例模式进行控制访问git

  • 用户信息存储及转发
    • 用户信息存储仓的设置
      serverUser的实体bean在设计时采用的是 ConcurrentLinkedQueue做为信息存储仓的数据结构,保证在多线程下的安全。
    • 每次server端读取client端发送的comment将数据发送到对应user的warehouse(数据仓)中,接着读取其控制用户的warehouse,执行命令。

client

  • 总体基本架构为MVC
    model层经过control进行数据交互同时control层进行login和chatroom界面切换控制。
  • 基本界面切换
    以前对javafx不熟悉,根据写andorid经验,总以为Javafx的界面切换不是很方便。初期将界面写了出来,后期进行了界面切换方式的修改。
    参考JavaFX - 实现管理多个Stage窗口及源码解析

一些值得注意的问题

  • gson的使用

    gson 的好用没必要多说,写的时候发现一个小问题gson 在使用时会将Integer以及int都会转为Double或者double类型
    解决方案以下解决gson将Integer默认转换成Double的问题github

  • javafx UI界面更新

    • 相似于android在UI界面只能在UI线程中进行更改,在javafx中也是如此。不过以前Android知道其异步方式的实现
      在javafx中查阅资料后总结下其更改界面的方法数据库

      Platform.runLater(new Task<String>() {
        @Override
        protected String call() throws Exception {
           //do UI operato
            return null;
        }
      });

      文件路径

      在写图片的显示时发现了显示的问题,特意的查了这部分的材料,其中比较好的几篇
      Java中文件的相对路径与绝对路径
      Java中文件路径及其访问json

      emoji表情的实现

  • 方案1 传统emoji的表情的实现小程序

    其实早在2010年,Unicode编码就已经归入了700多个Emoji表情,因此是能够支持表情的,只要加载支持Emoji表情的字库便可 连接How to support Emojis (Part1)安全

    可是emoji的显示时要依赖于平台的,以前在Android端写过的emoji实现因为和ios端不统一也从新定制了一份
    • 附上对比
      Android

      javafx

      简直要丑哭了
    • 实现方式
      emoji 的编码方式

      java中String 采用 UTF-16 编码方式存储全部字符, getBytes(String charsetName)也就是转为UTF-8 便可实现编码转换。将其输出便可显示emoji
  • 方案2 以前在Android端经过对SpannableString 的处理实现添加任何的图片到文本中
    根据这个思路 参考EmojiOneJava实现了功能.
    并且javafx的textArea不支持 文字加图片, 在java分fx中textflow能够存放子组件,因此显示界面使用textflow,输入界面使用textArea,显示的表情以表情简写表示

项目地址We Chat

相关文章
相关标签/搜索