web网页端使用webSocket实现语音通话功能(SpringBoot+VUE)
后台-插件-广告管理-内容页头部广告(手机) |
写在前面
最近在写一个web项目,需要实现web客户端之间的语音通话,期望能够借助webSocket全双工通信的方式来实现,但是网上没有发现可以正确使用的代码。网上能找到的一个代码使用之后只能听到“嘀嘀嘀”的杂音
解决方案:使用Json来传递数据代替原有的二进制输入输出流
技术栈:VUE3、SpingBoot、WebSocket
Java后端代码
pom.xml
配置Maven所需的jar包
<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-websocketartifactId> dependency>- 1
- 2
- 3
- 4
WebSocketConfig.java
webSocket配置类
package com.shu.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { /** * 注入ServerEndpointExporter, * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
WebSocketAudioServer.java
webSocket实现类,其中roomId是语音聊天室的id,userId是发送语音的用户id
所以前端请求加入webSocket时候的请求样例应该是:ws://localhost:8080/audio/1/123这个请求中1是roomId,123是userId,这里建议使用ws,一般来说ws对于http,wss对应https
package com.shu.socket; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import jakarta.websocket.OnClose; import jakarta.websocket.OnError; import jakarta.websocket.OnMessage; import jakarta.websocket.OnOpen; import jakarta.websocket.Session; import jakarta.websocket.server.PathParam; import jakarta.websocket.server.ServerEndpoint; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; /** * @Author:Long **/ @Component @Slf4j @ServerEndpoint(value = "/audio/{roomId}/{userId}") public class WebSocketAudioServer { private static ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<String, Session>(); private static CopyOnWriteArraySet<WebSocketAudioServer> webSocketSet = new CopyOnWriteArraySet<>(); private Session webSocketsession; private String roomId; private String userId; @OnOpen public void onOpen(@PathParam(value = "roomId") String roomId, @PathParam(value = "userId") String userId, Session webSocketsession) { // 接收到发送消息的人员编号 this.roomId = roomId; this.userId = userId; // 加入map中,绑定当前用户和socket sessionPool.put(userId, webSocketsession); webSocketSet.add(this); this.webSocketsession = webSocketsession; // 在线数加1 addOnlineCount(); System.out.println("user编号:" + userId + ":加入Room:" + roomId + "语音聊天 " + "总数为:" + webSocketSet.size()); } @OnClose public void onClose() { try { sessionPool.remove(this.userId); } catch (Exception e) { } } @OnMessage(maxMessageSize = 5242880) public void onMessage(@PathParam(value = "roomId") String roomId, @PathParam(value = "userId") String userId, String inputStream) { try { for (WebSocketAudioServer webSocket : webSocketSet) { try { if (webSocket.webSocketsession.isOpen() && webSocket.roomId.equals(roomId) && !webSocket.userId.equals(userId)) { webSocket.webSocketsession.getBasicRemote().sendText(inputStream); } } catch (Exception e) { e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } } @OnError public void onError(Session session, Throwable error) { error.printStackTrace(); } /** * 为指定用户发送消息 * */ public void sendMessage(String message) throws IOException { // 加同步锁,解决多线程下发送消息异常关闭 synchronized (this.webSocketsession) { this.webSocketsession.getBasicRemote().sendText(message); } } public List<String> getOnlineUser(String roomId) { List<String> userList = new ArrayList<String>(); for (WebSocketAudioServer webSocketAudioServer : webSocketSet) { try { if (webSocketAudioServer.webSocketsession.isOpen() && webSocketAudioServer.roomId.equals(roomId)) { if (!userList.contains(webSocketAudioServer.userId)) { userList.add(webSocketAudioServer.userId); } } } catch (Exception e) { e.printStackTrace(); } } return userList; } }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
VUE前端代码
audioChat.vue
这段代码是博主从自己的vue代码中截取出来的(原本的代码太多了),可能有些部分代码有函数没写上(如果有错的话麻烦大家在评论区指出,博主会及时修改)
注意事项
之前有博客使用二进制数据输入输出流来向后端传输数据,但是功能无法实现,后来发现那位博主的数据并没有发成功,我直接在Java中使用Json来传输float数组数据,实现了语音通话功能。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
关于Chrome或Edge浏览器报错
关于谷歌浏览器提示TypeError: Cannot read property ‘getUserMedia’ of undefined
解决方案:
1.网页使用https访问,服务端升级为https访问,配置ssl证书
2.使用localhost或127.0.0.1 进行访问
3.修改浏览器安全配置
在chrome浏览器中输入如下指令
chrome://flags/#unsafely-treat-insecure-origin-as-secure- 1
开启 Insecure origins treated as secure
在下方输入栏内输入你访问的地址url,然后将右侧Disabled 改成 Enabled即可
浏览器会提示重启, 点击Relaunch即可
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
在线投稿:投稿 站长QQ:1888636
后台-插件-广告管理-内容页尾部广告(手机) |