首页 > 编程语言 >项目实战:JavaFX + Netty 仿微信聊天程序(注册、登录、查好友、聊天)

项目实战:JavaFX + Netty 仿微信聊天程序(注册、登录、查好友、聊天)

时间:2022-12-24 16:46:33浏览次数:42  
标签:Netty java String void JavaFX ret 聊天 new public

记录一下使用JavaFX + Netty开发仿微信聊天程序 --- 米虫IM。

功能需求

米虫IM已经完成的功能有:

  • 用户注册功能
  • 用户登录功能
  • 搜索好友功能
  • 添加好友功能
  • 文本聊天功能
  • 离线消息功能

架构设计

米虫IM,主要划分为界面层,通讯层和基础层,界面采用JavaFX开发,可独立运行调试,通讯层采用Netty开发,采用C/S架构,分为服务端和客户端。

单机演示

单机版不需要运行服务端,单纯为JavaFX程序,可以独立运行,调试:

单机调试只需要实现通讯接口即可进行测试、调试:

public interface Caller {

    void register(String nickname, String username, String password);

    void login(String username, String password);

    void fetchChatList();

    void fetchFriendList();

    void readMessage(long friendId);

    void chat(long friendId, String message);

    void queryFriend(String nickname);

    void addFriend(long friendId);

    void applyAddFriend(long friendId);
}

一个实现案例:

public class DebugCaller implements Caller {
    @Override
    public void register(String nickname, String username, String password) {
        UserRet ret = new UserRet();
        ret.setId(1);
        ret.setNickname(nickname);
        ret.setUsername(username);
        FXListenerContext.onRegister(0, ret, null);
    }

    @Override
    public void login(String username, String password) {
        UserRet ret = new UserRet();
        ret.setId(1);
        ret.setNickname("米虫2022");
        ret.setUsername(username);
        FXListenerContext.onLogin(0, ret, null);
    }

    @Override
    public void fetchChatList() {
        String[] users = new String[]{"阿德莱德", "东南墨尔本凤凰", "独行侠", "南安普顿", "步行者"/*, "JavaScript"*/};
        String[] messages = new String[]{"F1意大利大奖赛第二次练习赛", "全运会-羽毛球男团决赛", "2021ECEA东亚电竞锦标赛英雄联盟G3",
                "英超第4轮 曼联", "世界职业拳王争霸赛"/*, "全运会-跳水男子三米板决赛 全运会"*/};
        List<ChatRet> chatRetList = new ArrayList<>();
        for (int i = 0; i < users.length; i++) {
            ChatRet chatRet = new ChatRet();
            chatRet.setType(ChatRet.TEXT);
            chatRet.setFriendId(i);
            chatRet.setNickname(users[i]);
            chatRet.setMessage(messages[i]);
            chatRet.setTimestamp(System.currentTimeMillis() - new Random().nextInt(10) * 24 * 60 * 60 * 1000);
            chatRet.setMessageCount(new Random().nextInt(150));
            if (i == users.length - 1) {
                chatRet.setMessageCount(0);
            }
            chatRetList.add(chatRet);
        }
        ChatRet ret = new ChatRet();
        ret.setFriendId(1001);
        ret.setTimestamp(System.currentTimeMillis());
        ret.setType(ChatRet.ADD_FRIEND);
        ret.setNickname("米虫2022");
        ret.setMessageCount(1);
        ret.setMessage("1001");
        chatRetList.add(ret);
        FXListenerContext.onFetchChatList(0, chatRetList, null);
    }

    @Override
    public void fetchFriendList() {
        String[] users = new String[]{"阿德莱德", "东南墨尔本凤凰", "独行侠", "南安普顿", "步行者", "珀斯野猫"};
        List<UserRet> userRetList = new ArrayList<>();
        for (int i = 0; i < users.length; i++) {
            UserRet userRet = new UserRet();
            userRet.setId(i);
            userRet.setNickname(users[i]);
            userRetList.add(userRet);
        }
        FXListenerContext.onFetchFriendList(0, userRetList, null);
    }

    @Override
    public void readMessage(long friendId) {
    }

    @Override
    public void chat(long friendId, String message) {
        ChatRet chatRet = new ChatRet();
        chatRet.setFriendId(friendId);
        chatRet.setType(ChatRet.TEXT);
        chatRet.setNickname("机器人自动回复");
        chatRet.setMessage("我是复读机:" + message);
        chatRet.setTimestamp(System.currentTimeMillis());
        FXListenerContext.onChat(chatRet);
    }

    @Override
    public void queryFriend(String nickname) {
        String[] users = new String[]{"Java", "C", "C++", "Python", "Go", "JavaScript"};
        List<UserRet> userRetList = new ArrayList<>();
        for (int i = 0; i < users.length; i++) {
            UserRet userRet = new UserRet();
            userRet.setId(i);
            userRet.setNickname(users[i]);
            userRetList.add(userRet);
        }
        FXListenerContext.onQueryFriend(0, userRetList, null);
    }

    @Override
    public void addFriend(long friendId) {
    }

    @Override
    public void applyAddFriend(long friendId) {
        new Thread(() -> {
            try {
                TimeUnit.MICROSECONDS.sleep(30);
            } catch (InterruptedException e) {
            }
            ChatRet ret = new ChatRet();
            ret.setFriendId(1001);
            ret.setTimestamp(System.currentTimeMillis());
            ret.setType(ChatRet.ADD_FRIEND_RET);
            ret.setNickname("米虫2022");
            ret.setMessageCount(1);
            ret.setMessage("我们已经是好友了,开始聊天吧!");
            FXListenerContext.onChat(ret);
        }).start();
    }
}

通讯演示

通讯版需要先运行Netty开发的服务端,然后运行多个客户端进行通讯:

Netty通讯版只要引入JavaFX包实现上面的Caller即可。

public class ImCaller implements Caller {

    @Override
    public void register(String nickname, String username, String password) {
        RegisterBO bo = new RegisterBO();
        bo.setName(nickname);
        bo.setUsername(username);
        bo.setPassword(password);
        ImContext.sendBO(Type.register, bo);
    }

    @Override
    public void login(String username, String password) {
        LoginBO bo = new LoginBO();
        bo.setUsername(username);
        bo.setPassword(password);
        ImContext.sendBO(Type.login, bo);
    }

    @Override
    public void fetchChatList() {
        ImContext.sendBO(Type.fetch_chat, new EmptyBO());
    }

    @Override
    public void fetchFriendList() {
        ImContext.sendBO(Type.fetch_friend, new EmptyBO());
    }

    @Override
    public void readMessage(long friendId) {
        ImContext.sendBO(Type.rend_message, new StringBO(String.valueOf(friendId)));
    }

    @Override
    public void chat(long friendId, String message) {
        ChatBO bo = new ChatBO();
        bo.setContent(message);
        bo.setToUserId(friendId);
        bo.setType(ChatBO.Type.text);
        ImContext.sendBO(Type.chat, bo);
    }
    @Override
    public void queryFriend(String nickname) {
        ImContext.sendBO(Type.query_friend, new StringBO(nickname));
    }

    @Override
    public void addFriend(long friendId) {
        StringBO bo = new StringBO();
        bo.setContent(String.valueOf(friendId));
        ImContext.sendBO(Type.add_friend, bo);
    }

    @Override
    public void applyAddFriend(long friendId) {
        ImContext.sendBO(Type.apply_add_friend, new StringBO(String.valueOf(friendId)));
    }
}

关于源码

需要源码的扫描左侧头像微信小程序或私信联系,单机版源码结构如下:

.
├── App.java
├── AppStarter.java
├── caller
│   ├── Caller.java
│   └── DebugCaller.java
├── component
│   ├── FX.java
│   ├── FXContext.java
│   ├── FXImage.java
│   └── FXUI.java
├── javascript
│   ├── HTMLBuilder.java
│   └── JSMember.java
├── listener
│   ├── ChatListener.java
│   ├── ErrorListener.java
│   ├── FXListenerContext.java
│   ├── FetchChatListListener.java
│   ├── FetchFriendListListener.java
│   ├── LoginListener.java
│   ├── QueryFriendListener.java
│   ├── RegisterListener.java
│   └── ret
│       ├── ChatRet.java
│       └── UserRet.java
├── model
│   ├── AppMO.java
│   ├── ChatMO.java
│   ├── FriendMO.java
│   ├── LoginMO.java
│   └── RegisterMO.java
└── ui
    ├── UserDataController.java
    ├── chat
    │   ├── ChatAddFriendDialog.java
    │   ├── ChatItemController.css
    │   ├── ChatItemController.fxml
    │   ├── ChatItemController.java
    │   ├── ChatListController.css
    │   ├── ChatListController.fxml
    │   ├── ChatListController.java
    │   ├── ChatMainController.css
    │   ├── ChatMainController.fxml
    │   └── ChatMainController.java
    ├── friend
    │   ├── FriendAddController.fxml
    │   ├── FriendAddController.java
    │   ├── FriendAddItemController.fxml
    │   ├── FriendAddItemController.java
    │   ├── FriendAddStage.java
    │   ├── FriendItemController.css
    │   ├── FriendItemController.fxml
    │   ├── FriendItemController.java
    │   ├── FriendListController.css
    │   ├── FriendListController.fxml
    │   ├── FriendListController.java
    │   ├── FriendProfileController.css
    │   ├── FriendProfileController.fxml
    │   └── FriendProfileController.java
    ├── login
    │   ├── LoginController.fxml
    │   ├── LoginController.java
    │   ├── LoginForm.java
    │   └── LoginStage.java
    ├── main
    │   ├── MainController.css
    │   ├── MainController.fxml
    │   └── MainController.java
    └── register
        ├── RegisterController.fxml
        ├── RegisterController.java
        └── RegisterForm.java

12 directories, 60 files

标签:Netty,java,String,void,JavaFX,ret,聊天,new,public
From: https://www.cnblogs.com/michong2022/p/17002999.html

相关文章

  • #PHP #MySQL数据操作 #在线聊天 PHP实现在线聊天与MySQL的“增查删改”
     目录1.目标图2.项目简介 3.目录结构 4.建立MySQL表 5.实现过程 5.1index.php5.2data.php 5.2method.php5.3 case.php5.4main.js5.5css/style.cs......
  • 人工智能聊天DEMO
    importurllib.parseimportrequests#调用机器人接口defqingyunke(msg): url="http://api.qingyunke.com/api.php?key=free&appid=0&msg=%s"%(urllib.parse.qu......
  • 基于Netty的IM聊天加密技术学习:一文理清常见的加密概念、术语等
    1、引言在社区中,分享了很多篇基于Netty编写的IM聊天入门文章(比如《跟着源码学IM》系列、《基于Netty,从零开发IM》系列等),在这些文章中分享了各种IM通信算法原理和功能逻辑......
  • Netty入门
    1.简介异步,基于事件驱动的网络应用框架TCP/IP=>JDK原生=>NIO===>Netty《netty实战》《netty权威指南》2.应用基于网络的高并发或者网络的通信RPC框架远程服务调用,......
  • 【php】swoole中websoket创建在线聊天室
    swoole中websoket创建在线聊天室(php)swoole现仅支持Linix,macos创建websocket服务器首先现在服务器创建一个websocket服务器<?php//创建websocket服务器$server=new......
  • Netty-介绍-1
    Netty介绍和应用场景要求已经掌握了主要技术构成:JavaOOP编程、Java 多线程编程、JavaIO编程、Java 网络编程、常用的Java设计模式(比如 观察......
  • Netty应用之入门实例
    一、​​Linux​​​五大网络​​IO​​模型我们在学些​​netty​​​我们需要了解下​​linux​​​的​​IO​​​模型,我们的​​java​​​的​​IO​​模型也是在此基......
  • JavaFX和swing、swt、awt 的区别?
    ......
  • Netty中的Decoder和Encoder作用
    什么是编解码器每个网络应用程序都必须定义如何解析在两个节点之间来回传输的原始字节,以及如何将其和目标应用程序的数据格式做相互转换;这种转换逻辑有编解码器处理,编解码......
  • 我做了第一个ChatGPT .net api聊天库
    最近这个ChatGPT很火啊,看了B站上很多视频,自己非常手痒,高低自己得整一个啊,但是让我很难受的是,翻遍了github前十页,竟然没有一个C#的ChatGPT项目,我好难受啊!那能怎么办?自己搞......