websocket的介绍就不多说了,简单来说就是http协议只能支持客户端访问springboot的接口,然后springboot返回相应的数据,但是ws的协议是可以主动向用户的客户端发送消息,所以可以用来做实时传输。

接下来由浅入深,一步一步来做完这个聊天室,不同阶段的代码我会放在网盘,可以根据需要自取。

首先创建一个基础的Springboot项目 

启动类,只要能启动就可以

package com;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import springfox.documentation.swagger2.annotations.EnableSwagger2;

@SpringBootApplication

@EnableSwagger2

@MapperScan(basePackages = { "com.mapper" })

public class ChatDemo {

public static void main(String[] args) {

SpringApplication.run(ChatDemo.class, args);

}

}

在pom.xml中导入websocket环境

org.springframework.boot

spring-boot-starter-websocket

创建启动websocket支持的.java文件

这个类会在springboot启动的时候自动注入,所以复制粘贴过去就可以了。

package com.config;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.socket.server.standard.ServerEndpointExporter;

//启动websocket支持

@Configuration

public class WebSocketConfig {

@Bean

public ServerEndpointExporter serverEndpointExporter() {

return new ServerEndpointExporter();

}

}

  创建websocket启动类

        下面时一个简化过的启动类,虽然我们最终目标是写聊天室,但是最基本的还是先搞清楚最基础的websocket的连接,网上大部分的教程都有不同程度的魔改过,代码阅读难度较高,所以我将网上的代码进行了简化方便入门和魔改。

package com.server;

import java.io.IOException;

import javax.websocket.OnClose;

import javax.websocket.OnError;

import javax.websocket.OnMessage;

import javax.websocket.OnOpen;

import javax.websocket.Session;

import javax.websocket.server.PathParam;

import javax.websocket.server.ServerEndpoint;

import org.springframework.stereotype.Component;

/**

* 客户端访问该链接即可和服务端建立连接

*/

@ServerEndpoint("/login_connect/{userId}")

@Component

public class WebSocketServer {

//使用session向连接的用户发送信息

private Session session;

//记录连接到此socke的用户id

private String userId = "";

//用户连接成功后会自动调用该方法

@OnOpen

public void onOpen(Session session, @PathParam("userId") String userId) throws

IOException {

this.session = session;

this.userId = userId;

System.out.println("连接成功,用户ID为:" + userId);

//连接成功后向连接的用户返回 “连接成功” 信息

this.session.getBasicRemote().sendText("连接成功");

}

//关闭连接后自动调用

@OnClose

public void onClose() {

System.out.println("close connect");

}

//收到用户发来的消息时调用

@OnMessage

public void onMessage(String message, Session session) throws IOException {

System.out.println("收到id为:"+this.userId+"的用户发来的消息:"+message);

}

//错误时调用

@OnError

public void onError(Session session, Throwable error) {

}

}

写完上述的代码后,就建立了最简单的服务端

接下来是客户端代码

因为是在本地跑所以我是直接在HbuilderX中创建的新的前端项目

下面是代码

websocket通讯

用户名:


发送的信息:


下面是运行效果

        1.前端运行截图

       2. 前端控制台,点击

        3.点击发送按钮后 springboot控制台

 

上述代码实现了最简单的客户端向服务端建立连接,然后服务端发送消息给客户端告知连接成功,然后客户端发送消息给服务端,实现了最简单的双向交互

我先把上面的代码压缩分享到这里,后面进行魔改,由于原始工程文件是之前用的另外一个项目的魔改框架,还保留了很多其他依赖,可能会有点大。

       链接:https://pan.baidu.com/s/1SYOZL58jugDNnaqqZ5yO-Q  提取码:1234  --来自百度网盘超级会员V2的分享

然后接下来我们把这个过程慢慢复杂化,比如上述的功能为服务端和客户端进行数据交换,接下来我们先来实现客户端对客户端的数据交互,也就是客户端A将消息发给服务端,然后服务端将消息发给客户端B。

 首先对上面的javasocket实现类进行一些修改(可以复制粘贴将原本的代码覆盖)

         因为一个websocket的实现类就说明连接了一个客户端,所以如果多个客户端连接到服务器的话,我们就可以创建一个容器来存放这些类,然后通过userid来区分,所以我们使用hashmap来存储这些连接,将该容器设为静态,然后我们可以在任意一个连接中调用所有的连接,就可以通过这个容器向任意用户发送消息。

// 用来存放所有的连接,静态

private static ConcurrentHashMap webSocketMap =

new ConcurrentHashMap<>();

        创建容器后,在OnOpen方法中添加将连接放入容器的方法。

// 用户连接成功后会自动调用该方法

@OnOpen

public void onOpen(Session session, @PathParam("userId") String userId) throws IOException {

this.session = session;

this.userId = userId;

System.out.println("连接成功,用户ID为:" + userId);

// 连接成功后向连接的用户返回 “连接成功” 信息

this.session.getBasicRemote().sendText("连接成功");

// 然后将该连接存入ChatController

webSocketMap.put(this.userId, this);

}

        接下来我们添加一个发送消息给该客户端的方法,方便客户端的连接被其他用户调用,然后就可以发送消息给该用户。

// 发送消息给此客户端

public void sendmessage(String message) throws IOException {

this.session.getBasicRemote().sendText(message);

}

         然后重写一下OnMessage方法,将用户发送过来的消息分解为json,内容为接收者id:receiveuserid、和发送的消息:message,当然从客户端传过来的数据为一条字符串,我们用JSON工具将他转化为对象,然后根据receiveruserid从SocketHashMap中取出相应的websocket连接,然后通过调用上面写的sendmessage方法将消息发送给接收者客户端。

// 收到用户发来的消息时调用

@OnMessage

public void onMessage(String message, Session session) throws IOException {

System.out.println(message);

JSONObject json = JSON.parseObject(message);

System.out.println(json.getString("receiveuserid") + "||" + json.getString("message"));

webSocketMap.get(json.getString("receiveuserid"))

.sendmessage("用户:" + this.userId + "说:" + json.getString("message"));

}

         改完后的代码如下:

package com.server;

import java.io.IOException;

import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;

import javax.websocket.OnError;

import javax.websocket.OnMessage;

import javax.websocket.OnOpen;

import javax.websocket.Session;

import javax.websocket.server.PathParam;

import javax.websocket.server.ServerEndpoint;

import org.apache.ibatis.annotations.Param;

import org.springframework.stereotype.Component;

import org.springframework.web.bind.annotation.RequestBody;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONObject;

import com.controller.ChatController;

import bean.Message;

/**

* 客户端访问该链接即可和服务端建立连接

*/

@ServerEndpoint("/login_connect/{userId}")

@Component

public class WebSocketServer {

// 用来存放所有的连接,静态

private static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();

// 使用session向连接的用户发送信息

private Session session;

// 记录连接到此socke的用户id

private String userId = "";

// 用户连接成功后会自动调用该方法

@OnOpen

public void onOpen(Session session, @PathParam("userId") String userId) throws IOException {

this.session = session;

this.userId = userId;

System.out.println("连接成功,用户ID为:" + userId);

// 连接成功后向连接的用户返回 “连接成功” 信息

this.session.getBasicRemote().sendText("连接成功");

// 然后将该连接存入ChatController

webSocketMap.put(this.userId, this);

}

// 关闭连接后自动调用

@OnClose

public void onClose() {

System.out.println("close connect");

}

// 收到用户发来的消息时调用

@OnMessage

public void onMessage(String message, Session session) throws IOException {

System.out.println(message);

JSONObject json = JSON.parseObject(message);

System.out.println(json.getString("receiveuserid") + "||" + json.getString("message"));

webSocketMap.get(json.getString("receiveuserid"))

.sendmessage("用户:" + this.userId + "说:" + json.getString("message"));

}

// 错误时调用

@OnError

public void onError(Session session, Throwable error) {

System.out.println("error");

}

// 发送消息给此客户端

public void sendmessage(String message) throws IOException {

this.session.getBasicRemote().sendText(message);

}

}

后端的代码改完了,然后前端代码也要进行一定的适配

        主要是添加了接收用户的id的输入框,js代码将发送的数据的格式写成了json,内容为receiverid和message。

websocket通讯

用户名:


接收人:


发送的信息:


运行效果:

        用户A界面:

        用户B界面:

         后端界面:

 第二阶段的代码,自取

链接:https://pan.baidu.com/s/1sDpelZH1n_bFUXEd46MgdQ  提取码:1234  --来自百度网盘超级会员V2的分享

 

接下来我们为这个聊天室添加一个群聊天室的功能

首先,当我们不再只是单纯的传输数据,而是聊天,那么消息就会复杂起来,所以我们先创建一个bean用来存储基本的消息

package com.entiry;

public class Message {

private String userid;//发送者id

private String message;//内容

private String type;//消息类型: new_user 新用户上线|| server 服务器消息|| tochatroom 聊天室消息|| offline 用户下线

public String getUserid() {

return userid;

}

public void setUserid(String userid) {

this.userid = userid;

}

public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

public String getType() {

return type;

}

public void setType(String type) {

this.type = type;

}

public String getTouser() {

return touser;

}

public void setTouser(String touser) {

this.touser = touser;

}

}

我在这边把消息类型分成了四种

new_user 新用户上线|| server 服务器消息|| tochatroom 聊天室消息|| offline 用户下线

客户端可以根据收到的消息不同的类型进行不同的操作

在我们使用Message类来进行数据传输后,就不能再跟以前一样,只传基本String了,而是把String复杂化了,也就是将Message类转化为JSON字符然后发送给前端然后前端再进行解析(其实可以直接将return 类型改成Message 但是因为中途改的话要改的代码蛮多的,我就懒得弄了)

然后我们继续魔改WebSocketServer

首先是添加一个向所有其他用户发送消息的方法

// 给除自己以外的所有用户发消息

public void sendmessagetootherusers(String message) throws IOException {

//获取所有连接中的用户id

Enumeration userkeys = webSocketMap.keys();

//通过便利来向所有用户发送消息

while (userkeys.hasMoreElements()) {

String userid = userkeys.nextElement();

//通过对比排除自己

if (userid != userId) {

webSocketMap.get(userid).sendmessage(message);

}

}

}

然后修改一下服务端收到消息的写法,把他复杂化

// 收到用户发来的消息时调用

@OnMessage

public void onMessage(String message, Session session) throws IOException {

//将收到的消息转化为JSON对象

JSONObject json = JSON.parseObject(message);

//判断消息类型,聊天室消息就直接将消息发送给所有除自己外的用户

if (json.getString("type").equals("tochatroom")) {

//创建消息类,将消息类型、消息内容、发送消息者的id放进去

Message msg = new Message();

msg.setMessage(json.getString("message"));

msg.setUserid(userId);

msg.setType("tochatroom");

//然后将消息发送给其他用户

sendmessagetootherusers(JSON.toJSONString(msg));

}

}

然后是当连接关闭的方法

// 关闭连接后自动调用

@OnClose

public void onClose() throws IOException {

// 将断开连接的socket从map中移除

webSocketMap.remove(userId);

// 给所有客户端发送offline消息类型,内容为离线用户的ID

Message msg = new Message();

msg.setType("offline");

msg.setMessage(userId);

sendmessagetootherusers(JSON.toJSONString(msg));

}

然后是当有客户端连接时

// 用户连接成功后会自动调用该方法

@OnOpen

public void onOpen(Session session, @PathParam("userId") String userId) throws IOException {

this.session = session;

this.userId = userId;

Message message = new Message();

message.setType("new_user");

message.setMessage(userId);

//将该连接加入到SocketMap中

webSocketMap.put(this.userId, this);

// 向所有用户广播,userid上线了

sendmessagetootherusers(JSON.toJSONString(message));

}

下面是完整代码

package com.server;

import java.io.IOException;

import java.util.Enumeration;

import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;

import javax.websocket.OnError;

import javax.websocket.OnMessage;

import javax.websocket.OnOpen;

import javax.websocket.Session;

import javax.websocket.server.PathParam;

import javax.websocket.server.ServerEndpoint;

import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONObject;

import com.entiry.Message;

/**

* 客户端访问该链接即可和服务端建立连接

*/

@ServerEndpoint("/login_connect/{userId}")

@Component

public class WebSocketServer {

// 用来存放所有的连接,静态

public static ConcurrentHashMap webSocketMap = new ConcurrentHashMap<>();

// 使用session向连接的用户发送信息

private Session session;

// 记录连接到此socke的用户id

private String userId = "";

// 用户连接成功后会自动调用该方法

@OnOpen

public void onOpen(Session session, @PathParam("userId") String userId) throws IOException {

this.session = session;

this.userId = userId;

Message message = new Message();

message.setType("new_user");

message.setMessage(userId);

//将该连接加入到SocketMap中

webSocketMap.put(this.userId, this);

// 向所有用户广播,userid上线了

sendmessagetootherusers(JSON.toJSONString(message));

}

// 关闭连接后自动调用

@OnClose

public void onClose() throws IOException {

// 将断开连接的socket从map中移除

webSocketMap.remove(userId);

// 给所有客户端发送offline消息类型,内容为离线用户的ID

Message msg = new Message();

msg.setType("offline");

msg.setMessage(userId);

sendmessagetootherusers(JSON.toJSONString(msg));

}

// 收到用户发来的消息时调用

@OnMessage

public void onMessage(String message, Session session) throws IOException {

// 将收到的消息转化为JSON对象

JSONObject json = JSON.parseObject(message);

// 判断消息类型,聊天室消息就直接将消息发送给所有除自己外的用户

if (json.getString("type").equals("tochatroom")) {

// 创建消息类,将消息类型、消息内容、发送消息者的id放进去

Message msg = new Message();

msg.setMessage(json.getString("message"));

msg.setUserid(userId);

msg.setType("tochatroom");

// 然后将消息发送给其他用户

sendmessagetootherusers(JSON.toJSONString(msg));

}

}

// 错误时调用

@OnError

public void onError(Session session, Throwable error) {

System.out.println("error");

}

// 给除自己以外的所有用户发消息

public void sendmessagetootherusers(String message) throws IOException {

// 获取所有连接中的用户id

Enumeration userkeys = webSocketMap.keys();

// 通过便利来向所有用户发送消息

while (userkeys.hasMoreElements()) {

String userid = userkeys.nextElement();

// 通过对比排除自己

if (userid != userId) {

webSocketMap.get(userid).sendmessage(message);

}

}

}

// 发送消息给此客户端

public void sendmessage(String message) throws IOException {

this.session.getBasicRemote().sendText(message);

}

}

然后我们需要一个Controller来让用户能有更复杂的操作

但是因为我们的项目是前后端分离项目,所以要写一些配置文件来支持外部访问

这个很简单,复制粘贴就可以了

package com.config;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.CorsRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration

public class CrossConfig implements WebMvcConfigurer {

@Override

public void addCorsMappings(CorsRegistry registry) {

registry.addMapping("/**")

.allowedOrigins("*")

.allowedMethods("GET","HEAD","POST","PUT","DELETE","OPTIONS")

.allowCredentials(true)

.maxAge(3600)

.allowedHeaders("*");

}

}

然后在创建Controller之前,我们再写一个类来存用户信息,好让客户端来获取当前已登录用户

(这里的代码很简单,有点脱裤子放屁,但是这种方式比较方便以后的扩展,虽然这个类里面只有userID,用数组也可以实现,但是当程序复杂后数据就多起来了,所以还是得习惯这种写法)

package com.entiry;

import java.io.Serializable;

public class User {

private String userID;//用户ID

public String getUserID() {

return userID;

}

public void setUserID(String userID) {

this.userID = userID;

}

}

然后是Controller方法 

package com.controller;

import com.server.WebSocketServer;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.socket.server.support.WebSocketHandlerMapping;

import java.util.ArrayList;

import java.util.Enumeration;

import java.util.List;

import java.util.concurrent.ConcurrentHashMap;

import com.entiry.User;

/**

* WebSocketController

*

* @author zhengkai.blog.csdn.net

*/

@RestController

public class ChatController {

//获取所有在线人员

@RequestMapping("/getUsers")

public List getUsers() {

//获取所有的用户名然后注入到列表里面然后返回给前端

List users = new ArrayList<>();

Enumeration userkeys = WebSocketServer.webSocketMap.keys();

while (userkeys.hasMoreElements()) {

String userid = userkeys.nextElement();

User tempuser = new User();

tempuser.setUserID(userid);

users.add(tempuser);

}

return users;

}

//查询某个用户是否在线,返回布尔型

@RequestMapping("/isOnline")

public boolean isOnline(@RequestBody String userid) {

System.out.println(userid);

return WebSocketServer.webSocketMap.containsKey(userid);

}

}

这个controller只实现了两个方法,但是拓展的话还是很方便的。

然后后端的内容就全做完了,接下来是修改前端来适配后端的代码,由于体量变大了,所以我把js css分开来写了

这边我先直接放出代码

HTML:

聊天室

聊天室

  | 用户名:

  

当前在线:人   

公共聊天室

CSS:

.main_block {

width: 700px;

height: 900px;

margin: 0 auto;

border: 1px solid black;

}

.top {

width: 100%;

height: 40px;

background-color: #47a9ff;

font-size: 20px;

color: white;

line-height: 40px;

text-align: center;

font-weight: bold;

}

.connect {

width: 100%;

height: 30px;

line-height: 30px;

font-size: 17px;

background-color: white;

}

.userid_input {

margin-top: 5px;

float: left;

}

.line {

float: left;

width: 100%;

height: 1px;

background-color: black;

}

.chat_room {

width: 100%;

height: 650px;

background-color: #fff;

}

.users {

width: 170px;

float: left;

overflow-y: scroll;

height: 100%;

}

.user {

cursor: pointer;

width: 100%;

height: 40px;

background-color: #9dcdff;

color: white;

line-height: 40px;

text-align: center;

font-style: 17px;

margin-bottom: 3px;

}

.user:hover {

background-color: #81baff;

}

.chat {

overflow-y: scroll;

width: 530px;

height: 100%;

float: left;

}

.messages {

width: 95%;

margin-left: 3%;

}

.sender_id {

margin-bottom: 5px;

font-weight: bold;

}

.sender_message {

margin-bottom: 5px;

width: 55%;

background-color: #9dcdff;

border-radius: 3px;

font-size: 15px;

padding: 7px;

}

.user_id {

margin-left: 85%;

margin-bottom: 5px;

font-weight: bold;

}

.user_message {

margin-left: 30%;

margin-bottom: 5px;

width: 55%;

background-color: #69ff8c;

border-radius: 3px;

font-size: 15px;

padding: 7px;

}

.send {

width: 100%;

height: 178px;

}

.text_input {

font-size: 15px;

background-color: #f3f3f3;

resize: none;

float: right;

border: 0px solid red;

width: 694px;

height: 130px;

}

.send_button {

margin-top: 5px;

float: right;

margin-right: 10px;

height: 30px;

width: 100px;

font-size: 15px;

font-weight: bold;

border: 0px solid red;

border-radius: 3px;

color: white;

background-color: #47a9ff;

}

.server_message {

width: 100%;

height: 30px;

font-size: 13px;

color: #9c9c9c;

float: left;

margin-left: 0%;

line-height: 30px;

text-align: center;

}

JS:

var socket = null;//socket连接

var userid = "";//当前用户id

var nowusercount = 0;//当前在线人数

//窗口运行时先获取一次在线列表

window.onload = function() {

getonlineusers();

}

//获取所有在线用户,然后把用户列表更新在列表中

function getonlineusers() {

$.ajax({

url: "http://localhost:8081/getUsers", //请求路径

//data: userid = "177", //要发送的数据

contentType: "application/json;charset=UTF-8", //发送数据的格式

type: "post", //访问方式

dataType: "text", //回调(常用json,text)

success: function(data) {

console.log(data);

var onlineusers = JSON.parse(data);

nowusercount = onlineusers.length

$("#nowusercount").text(nowusercount);

var list = '

公共聊天室
';

//将获取到的数据遍历然后存储在list中

for (var a = 0; a < onlineusers.length; a++) {

//排除自己

if (onlineusers[a].userID != userid) {

list = list + '

' + onlineusers[a].userID +

'

';

}

}

//将元素渲染在页面

$("#users").html(list);

}

});

}

//连接方法

function openSocket() {

//用户名不能输入为空

if ($("#userid").val() != "") {

userid = $("#userid").val();

//先查询一下是否已经有人用了这个用户名

$.ajax({

url: "http://localhost:8081/isOnline", //请求路径

data: userid = $("#userid").val(), //要发送的数据

contentType: "application/json;charset=UTF-8", //发送数据的格式

type: "post", //访问方式

dataType: "text", //回调(常用json,text)

success: function(data) {

//如果已经有人在使用这个用户名,则不继续往下走

if (data == "true") {

$("#tip").text("用户已存在");

setTimeout(function() {

$("#tip").text("");

}, 2500);

} else {

//当没人用过此用户名的时候则连接服务器

$("#tip").text("连接成功");

//将链接按钮和输入用户名的输入框设为不可用

$("#connect_botton").attr("disabled", true);

$("#userid").attr("disabled", true);

$("#connect_botton").text("已连接");

setTimeout(function() {

$("#tip").text("");

}, 2500);

//获取用户输入的用户id

userid = $("#userid").val();

$("#tittle").text("聊天室:" + userid);

//这个链接地址对应了springboot跑的端口和上面标注的访问的接口

var socketUrl = "ws://localhost:8081/login_connect/" + userid;

socket = new WebSocket(socketUrl);

//下面几个方法对应了服务端的几个方法

//连接成功

socket.onopen = function() {

//连接成功后获取最新在线用户列表

getonlineusers();

};

//发生了错误事件

socket.onerror = function() {

console.log("websocket发生了错误");

}

//收到消息

socket.onmessage = function(msg) {

console.log(msg.data);

var message = JSON.parse(msg.data);

//接收到的消息为new_user类型

//刷新用户列表然后提示用户上线

if (message.type == "new_user") {

getonlineusers();

nowusercount++;

$("#nowusercount").text(nowusercount);

sendservermessage("用户‘" + message.message + "’上线")

}

//接收到chatroom类型的消息直接展示在聊天室

if (message.type == "tochatroom") {

addothermessage(message.userid, message.message);

}

//接收到offline的消息提示离线然后刷新用户列表

if (message.type == "offline") {

sendservermessage("用户‘" + message.message + "’离线");

getonlineusers();

}

};

//关闭连接后运行

socket.onclose = function() {

console.log("websocket已关闭");

};

}

},

error: function() {}

});

} else {

$("#tip").text("请输入用户名");

setTimeout(function() {

$("#tip").text("");

}, 2500);

}

}

//发送数据给服务器

function sendMessage() {

if ($("#sendmessage").val() != "") {

//输入框中输入的消息类型为tochatroom

socket.send('{"type":"tochatroom","message":"' + $("#sendmessage").val() +

'"}');

addusermessage(userid, $("#sendmessage").val());

$("#sendmessage").val("");

}else{

$("#sendbutton").text("不能为空");

setTimeout(function() {

$("#sendbutton").text("发送消息");

}, 1500);

}

}

//将别人的消息渲染到页面

function addothermessage(sender, message) {

$("#messages").html($("#messages").html() + '

' +

sender + '

' + message + '
')

}

//将自己的消息渲染到页面

function addusermessage(userid, message) {

$("#messages").html($("#messages").html() + '

' +

userid + '

' + message + '
')

}

//将系统的消息渲染到页面

function sendservermessage(message) {

$("#messages").html($("#messages").html() + '

' + message + '
')

}

前端除js代码我都写好了注释,代码写的很简单,所以阅读起来难度也不大相信上手还是会很快的。

运行效果如下:

 

第三阶段源码 

链接:https://pan.baidu.com/s/11UemzHvQCSOVYWfsMrJ3mg  提取码:1234  --来自百度网盘超级会员V2的分享

这次做的聊天室因为没有用到数据库,所以不能进行登录,消息保存等操作,也没有实现加好友、删好友、私聊等功能,但是最基础的几个功能都已经实现了,如果是从阶段1开始设计的话,可以将这个项目复杂化,加上所有需要的功能,但是总的来说,会socket,和基础的数据库,那么上述功能都可以实现。

参考链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: