花了20分钟,给女朋友们写了一个web版群聊程序

编程

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。可以说WebSocket的出现,使得浏览器具备了实时双向通信的能力

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

原来为了实现推送,很多公司用的是Ajax 轮询,即按照特定的时间间隔,由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。而websocket就可以解决这些问题。

在Spring Boot中使用WebSocket

1.pom文件增加依赖

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-websocket</artifactId>

</dependency>

2.增加配置

@Configuration

public class WebSocketConfig {

@Bean

public ServerEndpointExporter serverEndpointExporter() {

return new ServerEndpointExporter();

}

}

3.Java代码

@Component

@ServerEndpoint("/websocket")

public class WebSocketServerController {

// 收到消息调用的方法

@OnMessage

public void onMessage(String message) {

System.out.println("收到的消息为 " + message);

}

// 建立连接调用的方法

@OnOpen

public void onOpen() {

System.out.println("Client connected");

}

// 关闭连接调用的方法

@OnClose

public void onClose() {

System.out.println("Connection closed");

}

// 传输消息错误调用的方法

@OnError

public void OnError(Throwable error) {

System.out.println("Connection error");

}

}

4.前端代码

<!DOCTYPE html>

<html>

<head>

<title>Testing websockets</title>

</head>

<body>

<div>

<textarea rows="3" cols="20" id="content"></textarea>

<br>

<input type="submit" value="Start" onclick="start()" />

</div>

<div id="messages"></div>

<script type="text/javascript">

var webSocket =

new WebSocket("ws://localhost:8080/websocket");

webSocket.onerror = function(event) {

onError(event)

};

webSocket.onopen = function(event) {

onOpen(event)

};

webSocket.onmessage = function(event) {

onMessage(event)

};

webSocket.onclose = function(event) {

onClose(event)

};

function onMessage(event) {

document.getElementById("messages").innerHTML

+= "<br />" + event.data;

}

function onOpen(event) {

document.getElementById("messages").innerHTML

= "Connection established";

}

function onError(event) {

alert(event);

}

function onClose(event) {

alert(event);

}

function start() {

var text = document.getElementById("content").value;

webSocket.send(text);

}

</script>

</body>

</html>

所以你看websocket其实很简单,前后端各写4个事件方法就行了(当然你也可以省略一些方法)

1.建立连接

2.收到消息

3.传输消息失败

4.关闭连接

事件和具体会话关联

如果事件想和具体会话关联,方法上只要加Session参数就行(4种事件类型的方法上都可加)

举个例子,直接将用户发送给服务端的话再返回给客户端

// 收到消息调用的方法

@OnMessage

public void onMessage(Session session, String message) {

try {

session.getBasicRemote().sendText(message);

} catch (IOException e) {

e.printStackTrace();

}

}

传递参数

方法上加@PathParam参数即可

@Component

@ServerEndpoint("/websocket/{sid}")

public class WebSocketServerController

@OnOpen

public void onOpen(@PathParam("sid") String sid) {

System.out.println("Client connected");

}

实现一个在线群聊

后端接口

@Slf4j

@Component

@ServerEndpoint("/groupChat/{sid}/{username}")

public class GroupChatController {

// 保存 组id->组成员 的映射关系

private static ConcurrentHashMap<String, List<Session>> groupMemberInfoMap = new ConcurrentHashMap<>();

// 收到消息调用的方法,群成员发送消息

@OnMessage

public void onMessage(@PathParam("sid") String sid,

@PathParam("username") String username, String message) {

List<Session> sessionList = groupMemberInfoMap.get(sid);

// 先一个群组内的成员发送消息

sessionList.forEach(item -> {

try {

String text = username + ": " + message;

item.getBasicRemote().sendText(text);

} catch (IOException e) {

e.printStackTrace();

}

});

}

// 建立连接调用的方法,群成员加入

@OnOpen

public void onOpen(Session session, @PathParam("sid") String sid) {

List<Session> sessionList = groupMemberInfoMap.get(sid);

if (sessionList == null) {

sessionList = new ArrayList<>();

groupMemberInfoMap.put(sid,sessionList);

}

sessionList.add(session);

log.info("Connection connected");

log.info("sid: {}, sessionList size: {}", sid, sessionList.size());

}

// 关闭连接调用的方法,群成员退出

@OnClose

public void onClose(Session session, @PathParam("sid") String sid) {

List<Session> sessionList = groupMemberInfoMap.get(sid);

sessionList.remove(session);

log.info("Connection closed");

log.info("sid: {}, sessionList size: {}", sid, sessionList.size());

}

// 传输消息错误调用的方法

@OnError

public void OnError(Throwable error) {

log.info("Connection error");

}

}

前端代码很简单,放github了

地址为:https://github.com/erlieStar/spring-boot-websocket

下面来看效果

注意先连接,后发送

在线开房地址:

http://www.javashitang.com:8090/

欢迎关注

参考博客

好文

[1]https://blog.csdn.net/moshowgame/article/details/80275084

[2]https://www.jianshu.com/p/d79bf8174196

[3]https://www.byteslounge.com/tutorials/java-ee-html5-websocket-example

一个群聊程序

[4]https://blog.csdn.net/moshowgame/article/details/80275084

以上是 花了20分钟,给女朋友们写了一个web版群聊程序 的全部内容, 来源链接: utcz.com/z/513187.html

回到顶部