WebRTC (Web Real-Time Communications)
- WebRTC (Web Real-Time Communications) 是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。WebRTC包含的这些标准使用户在无需安装任何插件或者第三方的软件的情况下,创建点对点(Peer-to-Peer)的数据分享和电话会议成为可能。
WebSocket
-
WebSocket是一种通信协议,可在单个TCP连接上进行全双工通信。WebSocket协议在2011年由IETF标准化为RFC 6455,后由RFC 7936补充规范。Web IDL中的WebSocket API由W3C标准化。
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。
基础配置
-
webSocket配置支持,涉及到@Autowired注入需要注意
-
项目启动时会初始化websocket,spring会为其注入service,此时@Autowired对象不为null
-
但是,spring默认管理单例模式,只会注入一次service,当新用户进入聊天,系统创建新的websocket对象,新的websocket对象不会被注入service,此时@Autowired为null报错
-
解决方式: stataic修饰 || 使用Spring自带的WebSocket实现方式
-
/** * 开启WebSocket支持 * * @author wangJiaLun * @date 2019-06-19 **/ @Configuration public class WebSocketConfig extends ServerEndpointConfig.Configurator{ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
-
-
配置websocket访问路径,以及主要方法说明
-
@Component @ServerEndpoint(value = "/websocket/chat",configurator = WebSocketConfig.class) public class WebsocketServer { /** * 连接建立成功调用的方法 * 判断接受人与当前登录人是否已经拥有房间,无则创建 * 输出历史消息 * @param session 会话 */ @OnOpen public void onOpen(Session session) { } /** * 收到客户端消息后调用的方法 * @param message 客户端发送过来的消息 * @param session 会话 */ @OnMessage public void onMessage(String message, Session session) { } /** * 当关闭浏览器后,则删除session记录和对话准备 */ @OnClose public void onClose(Session session) { } /** * 当发生异常错误调用的方法 * @param session 会话 * @param error 异常信息 */ @OnError public void onError(Session session, Throwable error) { } }
-
-
创建websocket连接
-
ws = new WebSocket("ws://192.168.3.102:8070/websocket/chat");
-
-
搭建webRTC信令
-
创建PeerConnection实例
-
var PeerConnection = (window.PeerConnection || window.webkitPeerConnection00 || window.webkitRTCPeerConnection || window.mozRTCPeerConnection);
-
-
前后信令转发交互流程
-
开始连接
-
前端创建webcket后在onopen方法中紧接着发送一条连接成功的数据
-
this.ws = new WebSocket("ws://192.168.3.102:8070/websocket/chat"); let self = this; this.ws.onopen = function(ev) { self.ws.sendJson({ messageHistoryVO: { senderId: , recipientId: }, messageTypeEnum: "CONNECTION_SUCCESS" }); };
-
会触发后端的@OnMessage的方法,如果后端不需要前端传递数据也可以不用这个步骤
-
直接在@OnOpen方法中完成业务逻辑
-
首先解析数据
-
MessageStruct messageStruct = new MessageStruct(); try { messageStruct = JSON.parseObject(message,MessageStruct.class); }catch (Exception e){ e.printStackTrace(); } MessageContent messageContent = new MessageContent();
-
根据前端传递消息类型执行不同步骤
-
switch (messageStruct.getMessageTypeEnum()){ case CONNECTION_SUCCESS: messageContent.setMessageState(new ConnectionSuccessMessageState()); break; case SINGLE_CHAT_TEXT: messageContent.setMessageState(new SingleChatMessageState()); break; case INITIATE_SINGLE_CHAT_AUDIO_VIDEO: messageContent.setMessageState(new InitiateSingleChatAudioVideoMessageState()); break; case ACCEPT_SINGLE_CHAT_AUDIO_VIDEO: messageContent.setMessageState(new AcceptSingleChatAudioVideoMessageState()); break; case SINGLE_SENDER_SIGNALING: messageContent.setMessageState(new SingleSenderSignalingState()); break; case CONNECTION_CLOSE: messageContent.setMessageState(new ConnetionCloseState()); break; default: ; } messageContent.doOperation(messageStruct.getMessageHistoryVO(), session);
-
-
音视频交互流程