美文网首页iOSWebRTCWebRTC
iOS入门学什么?—— 先写个简单的Demo,比如做个视频直播吧

iOS入门学什么?—— 先写个简单的Demo,比如做个视频直播吧

作者: 百里潋長 | 来源:发表于2016-12-06 10:40 被阅读0次
    aaa.jpeg

    惯例 ,WebRTC是什么####

    就是 Web browsers with Real-Time Communications 啊
    它是Google开源的啊,不要钱啊!

    为什么要用WebRTC?####

    就是老板叫看一下的啊
    它是Google开源的啊,不要钱啊!

    就是这样,不要在意太多细节 —— 百里潋長

    目标####

    在内网里使用iOS实现视频通话


    有了目标就很容易知道需要些什么

    服务器######

    WebRTC使用libjingle进行穿透,p2p传输数据,连接过程为
    尝试直连……
    尝试使用Stun Service进行穿透……
    尝试使用Turn Service进行中转……
    这里只进行内网视频通话,就不需要准备Stun以及Turn服务器了。但即便如此,在交换通信的元数据(信令)的时候依然需要一个服务器,并且WebRTC并没有统一实现 —— 我们还需要简单地实现一个信令服务器来支持这个Demo。
    我使用Java搭建信令服务器,WebSocket是一个用来做WebRTC信令的好方式,今后加上Web一起视频也是轻松加愉快

    iOS######
    1. Safari显然还没有支持WebRTC的视频通话,只能使用代码来实现,在这里使用libjingle_peerconnection库(传送门)来实现WebRTC通话
    2. iOS上使用WebSocket有一个非常不错的轮子SocketRocket(传送门)
    3. 其他常用库AFNetworkingReactiveCocoaMantleSVProgressHUDMasonry

    我们不生产代码,我们只是Github的搬运工 —— 农夫三拳,有点疼……


    从信令服务开始####

    JavaEE 7中出了JSR-356:Java API for WebSocket规范。我们需要使用JDK 7 以上版本,以Tomcat作为Web容器需要Tomcat 7.0.47 以上版本即可。
    Java WebSocket只是跑起来不可谓不简单,我们新建一个Java Web项目名字就随便叫做VideoMeeting好了。再随便创建一个SocketAction类来完成信令转发,只需要简单地标注@ServerEndpoint (访问地址)@OnOpen (新建连接)@OnClose (断开连接)@OnMessage (接受到消息) 这几个注解就可以完成工作

    package com.hsq.videomeeting.socketservice;
    
    import java.lang.reflect.Method;
    
    import javax.websocket.CloseReason;
    import javax.websocket.OnClose;
    import javax.websocket.OnError;
    import javax.websocket.OnMessage;
    import javax.websocket.OnOpen;
    import javax.websocket.Session;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;
    
    @ServerEndpoint("/socket/{userId}")
    public class SocketAction {
       private Session session;
       private int userId;
    
       @OnOpen
       public void onOpen(Session session, @PathParam(value="userId")int userId) {
           //注意 @ServerEndpoint 标注时声明了可以传入一个userId字段,此处再次声明并接收,作为用户及Session唯一标识
           this.userId = userId;
           this.session = session;
           //这是另一个随便写的处理类,将Session保存,必要时通过userid可以查找到并处理一些逻辑,此处省略,在OnMessage处有说明省了哪些逻辑的
           SocketService.addAction(this);
           System.out.println("打开连接:"+userId);
       }
       
       @OnClose
       public void onClose(CloseReason c) {
           SocketService.removeAction(this);
           System.out.println("关闭连接:"+userId);
       }
       
       @OnError
       public void onError(Throwable t) {
           
       }
       
       @SuppressWarnings("unchecked")
       @OnMessage
       public void onMessage(String message) {
           String decodeString = null;
           try {
               decodeString = new String(decodeBase64(message),"utf-8");
           } catch (Exception e) {
               e.printStackTrace();
           }
           System.out.println("消息 "+decodeString);
           //此处省略一点代码哟~
           //我传递的message是一个经过base64编码的JSON串,此处需要:
           //1、解析收到的message串,获取发送者id,接受者id以及消息主体内容
           //2、如果内容是offer/anwser/Candidate,则通过接受者id查找到其Session,使用send转发出去(offer什么的在后面客户端解释)
           //3、还有其他诸如接听、挂断、拒绝、正在通话中等等就自己脑洞啦
       }
       
       public boolean send(String jsonMessage){
           try {
               String base64JSON = encodeBase64(jsonMessage.getBytes("utf-8"));
               session.getBasicRemote().sendText(base64JSON);
               return true;
           } catch (Exception e) {
               e.printStackTrace();
               return false;
           }
       }
       
       /*** 
        * 编码
        */  
       @SuppressWarnings({ "rawtypes", "unchecked" })
       public static String encodeBase64(byte[] input) throws Exception {
           Class clazz=Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
           Method mainMethod= clazz.getMethod("encode", byte[].class);
           mainMethod.setAccessible(true);
            Object retObj=mainMethod.invoke(null, new Object[]{input});
            return (String)retObj;
       }  
       /*** 
        * 解码
        */  
       @SuppressWarnings({ "rawtypes", "unchecked" })
       public static byte[] decodeBase64(String input) throws Exception {
           Class clazz=Class.forName("com.sun.org.apache.xerces.internal.impl.dv.util.Base64");
           Method mainMethod= clazz.getMethod("decode", String.class);
           mainMethod.setAccessible(true);
            Object retObj=mainMethod.invoke(null, input);
            return (byte[])retObj;
       }
    
       public Session getSession() {
           return session;
       }
    
       public int getUserId() {
           return userId;
       }
    
       public void setUserId(int userId) {
           this.userId = userId;
       }
    
       @Override
       public int hashCode() {
           final int prime = 31;
           int result = 1;
           result = prime * result + userId;
           return result;
       }
       
       @Override
       public boolean equals(Object obj) {
           if (this == obj)
               return true;
           if (obj == null)
               return false;
           if (getClass() != obj.getClass())
               return false;
           SocketAction other = (SocketAction) obj;
           if (userId != other.userId)
               return false;
           return true;
       }
    }
    

    我们把它发布到Tomcat中运行起来,在iOS中尝试使用SocketRocket进行连接

    NSString * const WEBSOCKET_ADDRESS = @"ws://192.168.168.41:9999/VideoMeeting/socket/";
    NSString *urlStr = [NSString stringWithFormat:@"%@%d", WEBSOCKET_ADDRESS,[User user].userId];
    SRWebSocket  *socket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:urlStr]];
    socket.delegate = self;
    [socket open];
    

    这时就能在SRWebSocket的Delegate回调函数中获取到消息

    ////Delegate  -  WebSocket正常创建连接
    - (void)webSocketDidOpen:(SRWebSocket *)webSocket {
        NSLog(@"连接到信令服务器啦");
    }
    ////Delegate  -  接受消息的函数
    - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(NSString *)message {
        NSLog(@"接受到消息啦:%@",message);
    }
    

    有了信令服务器,不过还有关于用户体系和好友关系链之类的接口,不过不是视频必须并且与WebRTC无关,就不啰嗦了,接下来就开始着手敲iOS端的代码了啊喂

    相关文章

      网友评论

        本文标题:iOS入门学什么?—— 先写个简单的Demo,比如做个视频直播吧

        本文链接:https://www.haomeiwen.com/subject/ymolmttx.html