当前位置: 首页 > news >正文

cms做企业网站6温州品牌网站设计

cms做企业网站6,温州品牌网站设计,广州优俊网站制作公司,网站站内优化方案写在前面 最近在写一个web项目#xff0c;需要实现web客户端之间的语音通话#xff0c;期望能够借助webSocket全双工通信的方式来实现#xff0c;但是网上没有发现可以正确使用的代码。网上能找到的一个代码使用之后只能听到“嘀嘀嘀”的杂音 解决方案#xff1a;使用Jso…写在前面 最近在写一个web项目需要实现web客户端之间的语音通话期望能够借助webSocket全双工通信的方式来实现但是网上没有发现可以正确使用的代码。网上能找到的一个代码使用之后只能听到“嘀嘀嘀”的杂音 解决方案使用Json来传递数据代替原有的二进制输入输出流 技术栈VUE3、SpingBoot、WebSocket Java后端代码 pom.xml 配置Maven所需的jar包 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-websocket/artifactId /dependencyWebSocketConfig.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*/Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}WebSocketAudioServer.java webSocket实现类其中roomId是语音聊天室的iduserId是发送语音的用户id 所以前端请求加入webSocket时候的请求样例应该是ws://localhost:8080/audio/1/123这个请求中1是roomId123是userId这里建议使用ws一般来说ws对于httpwss对应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 int onlineCount 0;/** 存放每个客户端对应的MyWebSocket对象。实现服务端与单一客户端通信的话其中Key可以为用户标识 */private static ConcurrentHashMapString, Session sessionPool new ConcurrentHashMapString, Session();private static CopyOnWriteArraySetWebSocketAudioServer webSocketSet new CopyOnWriteArraySet();/** 与某个客户端的连接会话需要通过它来给客户端发送数据 */private Session webSocketsession;/** 当前发消息的人员编号 */private String roomId;private String userId;/*** 连接建立成功调用的方法* * param param 发送者ID是由谁发送的* param WebSocketsession 可选的参数。session为与某个客户端的连接会话需要通过它来给客户端发送数据*/OnOpenpublic void onOpen(PathParam(value roomId) String roomId, PathParam(value userId) String userId,Session webSocketsession) {// 接收到发送消息的人员编号this.roomId roomId;this.userId userId;// 加入map中绑定当前用户和socketsessionPool.put(userId, webSocketsession);webSocketSet.add(this);this.webSocketsession webSocketsession;// 在线数加1addOnlineCount();System.out.println(user编号: userId 加入Room: roomId 语音聊天 总数为: webSocketSet.size());}/*** 连接关闭调用的方法*/OnClosepublic 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();}}/*** 发生错误时调用** param session* param error*/OnErrorpublic void onError(Session session, Throwable error) {error.printStackTrace();}/*** 为指定用户发送消息** param message 消息内容* throws IOException*/public void sendMessage(String message) throws IOException {// 加同步锁解决多线程下发送消息异常关闭synchronized (this.webSocketsession) {this.webSocketsession.getBasicRemote().sendText(message);}}/*** 获取当前在线人数* * return 返回当前在线人数*/public static synchronized int getOnlineCount() {return onlineCount;}/*** 增加当前在线人数*/public static synchronized void addOnlineCount() {WebSocketAudioServer.onlineCount;}/*** 减少当前在线人数*/public static synchronized void subOnlineCount() {WebSocketAudioServer.onlineCount--;}public ListString getOnlineUser(String roomId) {ListString userList new ArrayListString();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;} } VUE前端代码 audioChat.vue 这段代码是博主从自己的vue代码中截取出来的原本的代码太多了可能有些部分代码有函数没写上如果有错的话麻烦大家在评论区指出博主会及时修改 注意事项 之前有博客使用二进制数据输入输出流来向后端传输数据但是功能无法实现后来发现那位博主的数据并没有发成功我直接在Java中使用Json来传输float数组数据实现了语音通话功能。 templatediv classplay-audiobutton clickstartCall refstart开始对讲/el-buttonbutton clickstopCall refstop结束对讲/el-button/div /templatescript setup // 语音聊天的变量 const audioSocket ref(null); let mediaStack; let audioCtx; let scriptNode; let source; let play; // 语音socket const connectAudioWebSocket () {//获取tokenconst token window.sessionStorage.getItem(token);if (!token) {return;}let url ws://localhost:8080/audio/1/123; //roomId:1 ,userId123audioSocket.value new WebSocket(url); // 替换为实际的 WebSocket 地址audioSocket.value.onopen () {console.log(audioSocket connected);};audioSocket.value.onmessage (event) {// 将接收的数据转换成与传输过来的数据相同的Float32Arrayconst jsonAudio JSON.parse(event.data);// let buffer new Float32Array(event.data);let buffer new Float32Array(4096);for (let i 0; i 4096; i) {// buffer.push(parseFloat(jsonAudio[i]));buffer[i] parseFloat(jsonAudio[i]);}// 创建一个空白的AudioBuffer对象这里的4096跟发送方保持一致48000是采样率const myArrayBuffer audioCtx.createBuffer(1, 4096, 16000);// 也是由于只创建了一个音轨可以直接取到0const nowBuffering myArrayBuffer.getChannelData(0);// 通过循环将接收过来的数据赋值给简单音频对象for (let i 0; i 4096; i) {nowBuffering[i] buffer[i];}// 使用AudioBufferSourceNode播放音频const source audioCtx.createBufferSource();source.buffer myArrayBuffer;const gainNode audioCtx.createGain();source.connect(gainNode);gainNode.connect(audioCtx.destination);var muteValue 1;if (!play) {// 是否静音muteValue 0;}gainNode.gain.setValueAtTime(muteValue, audioCtx.currentTime);source.start();};audioSocket.value.onclose () {console.log(audioSocket closed);};audioSocket.value.onerror (error) {console.error(audioSocket error:, error);}; }; // 开始对讲 function startCall() {isInChannel.value true;play true;audioCtx new AudioContext();connectAudioWebSocket();// 该变量存储当前MediaStreamAudioSourceNode的引用// 可以通过它关闭麦克风停止音频传输// 创建一个ScriptProcessorNode 用于接收当前麦克风的音频scriptNode audioCtx.createScriptProcessor(4096, 1, 1);navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then((stream) {mediaStack stream;source audioCtx.createMediaStreamSource(stream);source.connect(scriptNode);scriptNode.connect(audioCtx.destination);}).catch(function (err) {/* 处理error */isInChannel.value false;console.log(err, err);});// 当麦克风有声音输入时会调用此事件// 实际上麦克风始终处于打开状态时即使不说话此事件也在一直调用scriptNode.onaudioprocess (audioProcessingEvent) {const inputBuffer audioProcessingEvent.inputBuffer;// console.log(inputBuffer,inputBuffer);// 由于只创建了一个音轨这里只取第一个频道的数据const inputData inputBuffer.getChannelData(0);// 通过socket传输数据实际上传输的是Float32Arrayif (audioSocket.value.readyState 1) {// console.log(发送的数据,inputData);// audioSocket.value.send(inputData);let jsonData JSON.stringify(inputData);audioSocket.value.send(jsonData);// stopCall();}}; } // 关闭麦克风 function stopCall() {isInChannel.value false;play false;mediaStack.getTracks()[0].stop();scriptNode.disconnect();if (audioSocket.value) {audioSocket.value.close();audioSocket.value null;} } /script关于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 开启 Insecure origins treated as secure 在下方输入栏内输入你访问的地址url然后将右侧Disabled 改成 Enabled即可 浏览器会提示重启 点击Relaunch即可
http://www.zqtcl.cn/news/405409/

相关文章:

  • 网站布局企业安全文化建设导则
  • 胶东国际机场建设有限公司网站2021重大军事新闻
  • 企业网站优化的方式萍乡市建设局网站王丽
  • 做网站的收费标准社保网上服务大厅
  • php网站开发安全网站建设管理教程视频教程
  • 网站建设的空间是什么意思海络网站
  • 深圳华强北今晚网站优化推广公司
  • 网站建设行业好做吗太原网站改版
  • 寿光企业建站流程个人网站用什么软件
  • 网站建设与管理自考本全国卷wordpress 关闭文章修订
  • 兴义市建设局网站首页网站开发项目实训总结
  • 个人网站空间收费网络软文营销案例
  • 网站开发文件结构组成微网站移交
  • 西安全网优化 西安网站推广网页浏览器缩略词
  • 网站开发及企业推广营销型网站建设怎么收费
  • 网站建设与管理ppt课件百度云盘关键词推广营销
  • c asp.net网站开发书宁波建设业协会网站
  • 政务网站建设发言材料知名互联网公司有哪些
  • 网站搭建制作建e室内设计网画图
  • 重庆市建设工程施工安全管理信息网北京seo公司网站
  • 国外做调查问卷的网站建设邮费自己的网站 要不要购买服务器的
  • 网站建设和优化排名四川建设网官网证书查询入口
  • 如何搜名字搜到自己做的网站电子商务平台icp备案证明
  • 网站建设与管理工作内容北京网站建设价
  • 做网站选哪个语言软文营销的方法
  • 青岛正规公司网站建设公司中国建设银行注册网站
  • 免费个人网站平台关键词检索
  • 定制型网站建设推广宁河网站建设
  • 主流网站开发语言有哪些电子邮件营销
  • 扫描二维码进入公司网站怎样做在万网上域名了怎么做网站