探索实时通信新境界:ChatRoom —— 一个轻量级的在线聊天室应用

ChatRoom是一个开源的实时通信应用,使用WebSocket、Node.js等技术,适合学习RTC和提供即时通讯解决方案。易于部署,跨平台且具有高度可定制性,是开发者和小团队的理想选择。
摘要由CSDN通过智能技术生成

探索实时通信新境界:ChatRoom —— 一个轻量级的在线聊天室应用

ChatRoom局域网聊天系统项目地址:https://gitcode.com/gh_mirrors/chatroom4/ChatRoom

项目简介

是一个由 CCKevincyh 开发的开源项目,它提供了一个简单但功能齐全的在线聊天室平台。该项目旨在帮助开发者理解实时通信(RTC)的工作原理,并为小型团队或个人用户提供即时通讯的解决方案。

技术分析

ChatRoom 的核心技术栈主要包括以下组件:

  1. WebSocket:用于实现实时双向通信。相比传统的 HTTP 协议,WebSocket 提供了更低延迟、更高效的长连接通信方式,使得消息能够及时地在客户端和服务器之间传输。

  2. Node.js:作为后端开发环境,Node.js 使用 JavaScript 进行服务器编程,其非阻塞 I/O 模型非常适合处理大量并发连接。

  3. Vue.js:用于构建用户界面,Vue.js 的响应式数据绑定和组件化结构使得前端代码易于维护和扩展。

  4. Redis:作为缓存数据库,存储在线用户信息及聊天记录,提高了数据读取速度。

  5. JWT(JSON Web Tokens):实现用户认证和授权,保证了系统的安全性。

  6. HTML/CSS:构建简洁直观的用户界面,提供了良好的用户体验。

应用场景

ChatRoom 可以广泛应用于以下几个场景:

  • 学习与教学:教师可以创建房间进行在线讨论,学生无需安装额外软件即可参与。
  • 小型团队协作:团队成员可以在 ChatRoom 中快速分享想法,进行实时讨论。
  • 临时群组交流:例如线上活动、游戏比赛等,参与者可以快速建立临时聊天室进行沟通。
  • 实验与演示:开发者可以利用 ChatRoom 来演示实时通信技术的工作流程。

特点

  1. 易于部署:ChatRoom 提供了详细的部署指南,开发者甚至可以在短短几分钟内将服务搭建起来。
  2. 跨平台支持:适应各种浏览器和设备,无需下载应用,只需通过网页访问即可使用。
  3. 可定制性强:由于使用了模块化的开发模式,可以根据需求轻松修改和扩展功能。
  4. 源码开放:开源许可证允许自由查看、使用、修改源代码,鼓励社区贡献和协作。

结语

ChatRoom 作为一个轻量级、易部署且功能实用的在线聊天室,无论对于开发者学习 RTC 技术,还是对需要即时通讯功能的小团队和个人,都是一个值得尝试的选择。它的开源特性也为我们提供了宝贵的参考资料,便于我们理解和实践实时通信的应用。立即,开启您的实时通信之旅吧!

ChatRoom局域网聊天系统项目地址:https://gitcode.com/gh_mirrors/chatroom4/ChatRoom

chatRoom.zip 聊天室聊天室服务端 package chatroom; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashSet; import javax.swing.JFrame; import javax.swing.JOptionPane; /** * 聊天室服务器端 ChatRoomServer类 * * @version 1.01, 09/04/10 */ public class ChatRoomServer { private ServerSocket ss; /* 存放Socket的集合hs */ private HashSet<Socket> hs; public ChatRoomServer() { JFrame jf = new JFrame(); do { /* * 弹出输入对话框,提示输入服务器需要绑定的端口号 */ int port = Integer.parseInt(JOptionPane.showInputDialog(jf, "bind port:")); try { ss = new ServerSocket(port); System.out.println("server start success,now listening port:" + port); } catch (Exception e) { /* 弹出确认框进行确认 */ int op = JOptionPane.showConfirmDialog(jf, // 指定是在jf中弹出确认框 "bind fail,retry?", // 框体内容 "bind fail", // 对话框的标题 JOptionPane.YES_NO_OPTION); // 确认框按钮项 /* 如果选择'否',则退出程序 */ if (op == JOptionPane.NO_OPTION) { System.exit(1); } /* 打印异常栈信息 */ e.printStackTrace(); } } while (ss == null); /* 创建HashSet,用来存放Socket对象 */ hs = new HashSet<Socket>(); while (true) { try { /* 获得Socket,网络阻塞,等待客户端的连接 */ Socket s = ss.accept(); /* 一旦客户端连接上,则加入HashSet,便于维护 */ hs.add(s); /* 启动一个服务线程,为客户端服务 */ new ServerThread(s).start(); } catch (IOException e) { e.printStackTrace(); } } } /** * 成员内部类,服务线程类 */ class ServerThread extends Thread { private Socket s; public ServerThread(Socket s) { this.s = s; } @Override public void run() { BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(s .getInputStream())); while (true) { /* 从网络中读取客户端发出的消息 */ String str = br.readLine(); /* * 客户退出时的处理逻辑 规则:以"%EXIT_CHATROOM%"开头的消息为客户退出标记 */ if (str.charAt(0) == '%') { String com = str.split("%")[1]; if (com.equals("EXIT_CHATROOM")) { hs.remove(s); printMessage(str.split("%")[2] + ",leave!"); s.close(); break; } } else { /* 正常情况,直接向客户端群发消息 */ printMessage(str); } } } catch (IOException e) { e.printStackTrace(); } } /* * 负责为客户端群发消息 */ private void printMessage(String mes) { System.out.println(mes); try { /* 遍历所有Socket */ for (Socket s : hs) { PrintStream ps = new PrintStream(s.getOutputStream()); /* 产生发消息的时刻 */ Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); /* 向客户端发消息,消息结构为mes [yyyy-MM-dd HH:mm:ss] */ ps.println(mes + " [" + sdf.format(date) + "]"); /* 注意需要及时flush,清空缓冲区 */ ps.flush(); } } catch (IOException e) { e.printStackTrace(); } } } /* * 主方法,启动聊天室服务器端 */ public static void main(String[] args) { new ChatRoomServer(); } } 客户端窗体 package chatroom; import java.awt.BorderLayout; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; /** * 客户端窗口ChatRoomClientFrame类 负责客户端的视图表示、事件处理等逻辑 作为一个窗口,所以本类继承自JFrame * 为了实现事件处理,本类实现了ActionListener接口 * * @version 1.01, 09/04/10 */ public class ChatRoomClientFrame extends JFrame implements ActionListener { private static final long serialVersionUID = 3484437496861281646L; private JTextArea jta; // 多行文本域 private JLabel label; // 文本标签 private JTextField jtf; // 单行文本框 private JButton jb; // 按钮 private Socket socket; // socket 套接字 private String name; // 用户名 /* * ChatRoomClientFrame构造方法,负责初始化以及添加事件处理 */ public ChatRoomClientFrame(String name, Socket socket) { super("chatroom"); Font f = new Font("楷体", Font.BOLD, 20); /* 设置字体 */ jta = new JTextArea(10, 10); /* 创建10行10列的空多行文本域 */ jta.setEditable(false); /* 设置多行文本域为不可编辑 */ jta.setFont(f); /* 设置多行文本域字体 */ label = new JLabel(name + ":"); /* 创建带有用户名的文本标签 */ label.setFont(f); /* 设置文本标签字体 */ jtf = new JTextField(25); /* 创建单行文本框 */ jtf.setFont(f); /* 设置单行文本框字体 */ jb = new JButton("send"); /* 创建按钮 */ this.name = name; this.socket = socket; init(); /* 初始化,设置组件关系 */ addEventHandler(); /* 为组件添加事件监听 */ } /* * 初始化组件关系方法,供构造方法调用 */ private void init() { JScrollPane jsp = new JScrollPane(jta); this.add(jsp, BorderLayout.CENTER); JPanel jp = new JPanel(); jp.add(label); jp.add(jtf); jp.add(jb); this.add(jp, BorderLayout.SOUTH); } /* * 负责为各组件添加事件处理机制 */ private void addEventHandler() { jb.addActionListener(this); // 为jb添加事件监听,JButton点击触发事件 jtf.addActionListener(this); // 为jtf添加事件监听,JTextField敲回车触发事件 /* 设置JFrame默认关闭状态:DO_NOTHING_ON_CLOSE */ this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); /* 为JFrame添加窗口事件监听 */ this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent arg0) { /* 弹出确认框进行交互 */ int op = JOptionPane.showConfirmDialog( ChatRoomClientFrame.this, "exit?", "exit", JOptionPane.YES_NO_OPTION); if (op == JOptionPane.YES_OPTION) { try { PrintStream ps = new PrintStream(socket .getOutputStream()); /* 向服务器发送以%EXIT_CHATROOM%name为格式的串,代表退出信号 */ ps.println("%EXIT_CHATROOM%" + name); /* 注意需要及时flush */ ps.flush(); try { Thread.sleep(168); // 进行延时控制,防止提前关闭socket } catch (InterruptedException e) { e.printStackTrace(); } socket.close(); // 关闭客户端socket ps.close(); // 关闭流 } catch (IOException e) { e.printStackTrace(); } System.exit(1); // 退出程序 } } }); } /* * 实现事件处理方法 */ public void actionPerformed(ActionEvent ae) { try { PrintStream ps = new PrintStream(socket.getOutputStream()); ps.println(name + ": " + jtf.getText()); ps.flush(); /* 清空jtf中内容 */ jtf.setText(""); } catch (IOException e) { e.printStackTrace(); } } /* * 显示并执行窗口逻辑 */ public void showMe() { this.pack(); // 自动调整此窗口的大小 this.setVisible(true); // 设置窗口可见 /* * 启动线程,负责接收服务器端发来的消息 */ new Thread() { @Override public void run() { BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(socket .getInputStream())); while (true) { /* 从网络中读取服务器发出的数据 */ String str = br.readLine(); /* 对JTextArea进行追加消息 */ jta.append(str + "\n"); } } catch (IOException e) { e.printStackTrace(); } } }.start(); } } 客户端 package chatroom; import java.io.PrintStream; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JOptionPane; /** * 聊天室客户端 ChatRoomClient * * @version 1.01, 09/04/10 */ public class ChatRoomClient { private String name; // 用户名 private Socket socket; // Socket 套接字 private ChatRoomClientFrame frame; // 组合复用 ChatRoomClientFrame /* * ChatRoomClient构造方法,负责构造客户端表示逻辑 */ public ChatRoomClient() { JFrame jf = new JFrame(); /* * 弹出用户输入对话框,提示用户输入服务器的IP地址 返回相应字符串形式,存于变量serverIP,缺省值127.0.0.1 */ String serverIP = JOptionPane.showInputDialog(jf, "server IP:", "127.0.0.1"); /* * 弹出用户输入对话框,提示用户输入服务器端口号 转化为int形式返回,存于变量serverPort */ int serverPort = Integer.parseInt(JOptionPane.showInputDialog(jf, "port:")); /* * 弹出用户输入对话框,提示用户输入用户名,存于成员属性name */ name = JOptionPane.showInputDialog(jf, "your name:"); try { /* 通过IP和Port,与服务器端建立连接 */ socket = new Socket(serverIP, serverPort); /* 给服务器发消息 */ PrintStream ps = new PrintStream(socket.getOutputStream()); ps.println(name + ",login !"); } catch (Exception e) { JOptionPane.showMessageDialog(jf, "fail,check the connection!"); e.printStackTrace(); System.exit(1); } /* * 创建ChatRoomClientFrame,进行客户端主窗口的显示 */ frame = new ChatRoomClientFrame(name, socket); frame.showMe(); } /* * 主方法,启动聊天室客户端 */ public static void main(String[] args) { new ChatRoomClient(); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姚婕妹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值