引入的java包
<!-- 以下是即时通讯-->
<!-- Netty core modules -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.76.Final</version> <!-- 使用最新的稳定版本 -->
</dependency>
<!-- Optional: Support for WebSocket -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler-proxy</artifactId>
<version>4.1.76.Final</version>
</dependency>
<!-- Optional: Support for HTTP/2 -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-resolver-dns-native-macos</artifactId>
<version>4.1.76.Final</version>
<classifier>osx-x86_64</classifier>
<optional>true</optional>
</dependency>
2.创建project对象(这个对象是跟业务相关的,如果业务简单,不创建也可以,最后传输的都是字符串)
@Getter
@Setter
public class Project {
private GroupStudentService groupStudentService;
private Integer schoolId; //学校id
private Integer projectId; //项目id
private Integer leafId; //小节id
private Integer leafTypeId; //小节类型
private Integer chapterId; //章节id
private Object currentLeaf;//当前小节
private Integer currentLeafIndex;//当前小节的下标
private Integer currentChapterIndex;//当前章节的下标
public Project(Integer projectId,
Integer leafId,
Integer leafTypeId,
Integer chapterId,
Object currentLeaf,
Integer currentLeafIndex,
Integer currentChapterIndex,Integer schoolId) {
this.projectId = projectId;
this.leafId = leafId;
this.leafTypeId = leafTypeId;
this.chapterId = chapterId;
this.currentLeaf = currentLeaf;
this.currentLeafIndex = currentLeafIndex;
this.currentChapterIndex = currentChapterIndex;
this.schoolId= schoolId;
}
public Project() {
}
3.创建WebsocketHandler
public class WebsocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
// 定义一个全局变量用来保存所有连接的客户端Channel
private static final Set<Channel> connectedChannels = Collections.newSetFromMap(new ConcurrentHashMap<>());
// 当有新的连接时,将Channel添加到集合中
public void handlerAdded(ChannelHandlerContext ctx) {
connectedChannels.add(ctx.channel());
}
// 当连接关闭时,从集合中移除该Channel
public void handlerRemoved(ChannelHandlerContext ctx) {
connectedChannels.remove(ctx.channel());
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) {
String text = msg.text();
String prefix = text.substring(0, 7); //截取前缀
if (prefix.contains("switch")) {//当前数据是切换小节
handleSwitch(text.substring(7));
} else if (prefix.contains("xsData")) {//当前数据是学生提交作业给老师的
handleStudentData(text.substring(7));
}
}
//这个是专门用来切换小节的,老师切换上一节,下一节,跳到指定小节,学生的大屏页面也跟着切换
private void handleSwitch(String parts) {
//把parts转成jsonobject对象
JSONObject jsonObject = JSON.parseObject(parts);
Integer projectId = (int) jsonObject.get("projectId");
Integer leafId = (int) jsonObject.get("leafId");
Integer leafTypeId = (int) jsonObject.get("leafTypeId");
Integer chapterId = (int) jsonObject.get("chapterId");
Integer currentLeafIndex = (int) jsonObject.get("currentLeafIndex");
Integer currentChapterIndex = (int) jsonObject.get("currentChapterIndex");
Object currentLeaf = jsonObject.get("currentLeaf");
Integer schoolId = (int) jsonObject.get("institutionId");
Project project = new Project(projectId,
leafId,
leafTypeId,
chapterId,
currentLeaf,
currentLeafIndex,
currentChapterIndex, schoolId);
Gson gson = new Gson();
String jsonProject = gson.toJson(project);
if (project != null) {
for (Channel channel : connectedChannels) {
if (channel.isActive()) { // 检查通道是否仍然活跃
channel.writeAndFlush(new TextWebSocketFrame("switch:" + jsonProject));
}
}
}
}
//这个是专门用来学生提交数据的,学生提交数据,老师大屏上能展示数据
private void handleStudentData(String parts) {
//把parts转成jsonobject对象
JSONObject jsonObject = JSON.parseObject(parts);
Integer projectId =Integer.valueOf(jsonObject.get("projectId").toString());
Integer leafId = Integer.valueOf(jsonObject.get("leafId").toString());
Integer schoolId = Integer.valueOf( jsonObject.get("institutionId").toString());
Project project = new Project();
project.setProjectId(projectId);
project.setSchoolId(schoolId);
project.setLeafId(leafId);
Gson gson = new Gson();
String jsonProject = gson.toJson(project);
if (project != null) {
for (Channel channel : connectedChannels) {
if (channel.isActive()) { // 检查通道是否仍然活跃
channel.writeAndFlush(new TextWebSocketFrame("xsData:" + jsonProject));
}
}
}
}
4.创建WebsocketServer启动类
public class WebsocketServer {
public static void main(String[] args) throws InterruptedException {
initWebsocket();
}
public static void initWebsocket() throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
System.out.println("初始化WebsocketServer");
ChannelPipeline p = ch.pipeline();
p.addLast(new HttpServerCodec());
p.addLast(new HttpObjectAggregator(65536));
p.addLast(new ChunkedWriteHandler());
p.addLast(new WebSocketServerProtocolHandler("/screen"));
p.addLast(new WebsocketHandler());
}
});
ChannelFuture f = b.bind(8084).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}
5.页面上的发送数据
connectWebSocket() {
this.socket = new WebSocket('ws://' + window.location.hostname + ':8084/screen');
this.socket.addEventListener('open', (event) => {
console.log('WebSocket connection opened--学生');
});
this.socket.addEventListener('message', (event) => {
console.log(event);
});
this.socket.addEventListener('error', (event) => {
console.error('WebSocket error:', event);
});
this.socket.addEventListener('close', (event) => {
console.log('WebSocket connection closed');
});
}
///--------------------------------------------------这是scoket
let sendData = {
projectId: this.projectId,
leafId: this.leafId,
institutionId: JSON.parse(localStorage.getItem('user')).institutionId
};
console.log(sendData)
// 将数据对象转化为JSON字符串
let jsonData = JSON.stringify(sendData);
let prefixedData = 'xsData:' + jsonData;
this.socket.send(prefixedData);
///----------------------------------------------------------------
6.页面上接收数据
initWebSocket() {
this.socket = new WebSocket(`ws://${window.location.hostname}:8084/screen`);
this.socket.addEventListener('open', (event) => {
console.log('WebSocket connection opened');
});
this.socket.addEventListener('message', (event) => {
const data = event.data;
if (data.startsWith('xsData:')) {
const jsonData = data.substring(7);
const vo = JSON.parse(jsonData);
if (vo.schoolId == JSON.parse(localStorage.getItem('user')).institutionId &&
vo.projectId == this.projectId && vo.leafId == this.leafId
) {
this.getQd();
} else {
console.log("无效信息")
}
}
});
this.socket.addEventListener('error', (event) => {
console.error('WebSocket error:', event);
});
this.socket.addEventListener('close', (event) => {
console.log('WebSocket connection closed');
});
},