精华内容
下载资源
问答
  • iOS 使用websocket搭建本地服务器

    千次阅读 2019-04-28 17:42:59
    1、移动端何时需要搭建本地服务器? 当移动端与web端需要很强很即时的数据交互时,服务端只需要一个结果的时候,在移动端搭建本地服务器,然后让移动端与web端交互,完成一系列动作,把结果告诉服务端,实际应用...

    1、移动端何时需要搭建本地服务器?

    当移动端与web端需要很强很即时的数据交互时,服务端只需要一个结果的时候,在移动端搭建本地服务器,然后让移动端与web端交互,完成一系列动作,把结果告诉服务端,实际应用场景:积分墙。

    2、如何在移动端搭建本地服务器?

    (不知道怎么才能让我自己发布的资源免费)

    可以在csdn下载:https://download.csdn.net/download/u012717715/11149867

    在CocoaHttpServer基础上封装了routinghttp使用起来更方便

    也可以在git找资源,都是免费的

    //导入头文件
    #import "RoutingHTTPServer.h"
    #pragma mark -- 配置本地网络服务
    -(void)openServer{
        _httpServer = [[RoutingHTTPServer alloc] init];
        NSDictionary *bundleInfo = [[NSBundle mainBundle] infoDictionary];
        NSString *appVersion = [bundleInfo objectForKey:@"CFBundleShortVersionString"];
        if (!appVersion) {
            appVersion = [bundleInfo objectForKey:@"CFBundleVersion"];
        }
        NSString *serverHeader = [NSString stringWithFormat:@"%@/%@",
                                  [bundleInfo objectForKey:@"CFBundleName"],
                                  appVersion];
        [_httpServer setDefaultHeader:@"Server" value:serverHeader];
        [_httpServer setDefaultHeader:@"Content-Type" value:@"text/plain"];
        /*
        设置端口号,在调用的时候需要加上你设置的端口号
        http默认写端口号为80,如果设置为80则可以省略端口号
        https默认端口号为443,如果设置则省略
        */
        
        [_httpServer setPort:55433];
        
    
        //设置根目录
        NSString *webPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Web"];
        [_httpServer setDocumentRoot:webPath];
        [self setupRoutes];
        
        NSError *error;
        if ([_httpServer start:&error]) {
            NSLog(@"开启成功了");
        }
    }
    
    
    

    3、设置路由,与web交互(原理是封装了HttpServer中的方法)

    #pragma mark -- 配置路由
    - (void)setupRoutes {
        
        [self.http post:@"/" withBlock:^(RouteRequest *request, RouteResponse *response) {
            
            [response setHeader:@"Access-Control-Allow-Origin" value:@"*"];
    
            //请求参数
            NSDictionary *dicJson=[NSJSONSerialization JSONObjectWithData:[request body] options:NSJSONReadingMutableContainers error:nil];
            
            NSLog(@"%@",dicJson);
            
            if ([dicJson[@"type"] isEqualToString:@"check"]) {
        
                //响应
                [response respondWithString:dicJson[@"userId"]];
            }
    
        }];
        
    }
    
    
    

    其中  

    NSString *webPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Web"];

    [_httpServer setDocumentRoot:webPath];

    为设置服务器的根目录,和你使用nigx等搭建的服务器类似,设置根目录,只有拖进来后为蓝色文件夹才能访问到路径

    4、如何保持移动端后台不被kill?

    (现阶段的iOS 这些代码已经申请不到多少时间了,过几分钟就会被强制kill掉)

    -(void)applicationDidEnterBackground:(UIApplication *)application{
        
        [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
        
    }
    -(void)applicationWillEnterForeground:(UIApplication *)application {
        
        [[UIApplication sharedApplication] endBackgroundTask:UIBackgroundTaskInvalid];
        
    }
    

     

    5、web端代码

    关于如何配置 CocoaHttpServer支持https可以访问我的博文:https://blog.csdn.net/u012717715/article/details/90717513

    展开全文
  • 我们要做一个网页版的聊天室,当一个人发送了消息时,其他人怎么能看到这条信息呢?有一个做法就是在网页中不断的运行js,发送request给服务器服务器不断返回response,当有新的消息时显示在页面上。这样做...
        

    http协议,是客户端每发送一个request,服务器返回一个response,无法做到服务器主动向客户端发送数据。我们要做一个网页版的聊天室,当一个人发送了消息时,其他人怎么能看到这条信息呢?有一个做法就是在网页中不断的运行js,发送request给服务器,服务器不断返回response,当有新的消息时显示在页面上。这样做毫无疑问会产生大量的http连接,对服务器的性能和带宽都有影响。而websocket协议可以做到由服务器主动向客户端发送数据,当有新消息时就主动发送给浏览器,浏览器将内容更新到页面上。更多关于这个协议的详细内容和介绍,可以网上自行搜索。


    为了学习websocket,我们来实现一个超级简单的网页聊天室,建立一个html文件,页面显示效果如下,用一个大的div框架用来显示聊天记录,一个input输入内容,一个button用于发送信息:

    clipboard.png

    前端使用jssocket.io,代码如下:

    <script type="text/javascript" src="https://cdn.bootcss.com/socket.io/1.7.4/socket.io.min.js"></script>
    <script type="text/javascript" charset="utf-8">
        var socket = io.connect('http://' + document.domain + ':' + location.port);
        var send = function () {
            var msg = document.querySelector("input").value;
            socket.emit('my event', {data: msg});
        };
        socket.on('res', function (msg) {
            document.querySelector(".content").insertAdjacentHTML(
                "beforeend",
                "<div class='message-div'><span class='message-content'>" + msg.data + "</span></div>"
            )
        })
    </script>

    上段代码首先使用cdn引用socket.io.min.js,然后与后端建立连接,接着定义了一个send方法(在htmlbutton中使用onclikc绑定),该方法首先获取input中的内容,然后使用emit方法将其发送到后端,后端(python+Flask-SocketIO)对应的代码是:

    from flask import Flask, render_template
    from flask_socketio import SocketIO
    import config
    
    
    app = Flask(__name__)
    app.config.from_object(config)
    socketio = SocketIO(app)
    
    
    @app.route('/')
    def index():
        return render_template('websocket.html')
    
    
    @socketio.on('my event')
    def handle_my_custom_namespace_event(data):
        socketio.emit("res", data)
    
    
    if __name__ == "__main__":
        socketio.run(app)

    代码中使用@socketio.on('my event')注册一个my event事件(与前端socket.emit('my event', {data: msg})一致),然后再使用socketio.emit("res", data)将数据返回前端,前端又通过socket.on('res', callback)进行接收,所有建立了webscoket连接的客户端都会收到。此时整个流程就已经很明确了,再梳理一遍就是:点击button后,触发send函数,获取到input中的内容,然后将数据(准确来说是将携带数据的事件)发送给后端,后端对应这个事件的函数(即使用@socketio.on('my event')注册的函数,类似路由的注册)就会执行,该后端函数向前端发送携带同样数据的res事件,前端socket.on('res', callback)收到'req'事件后,使用callback回调函数处理(即向网页中添加内容)。


    开两个浏览器窗口,就可以看出效果了,如下:

    clipboard.png

    展开全文
  • WEBSOKET服务器搭建

    千次阅读 2013-06-27 14:32:06
    简单介绍一下tomcat的webSocketAPI使用: 在这里啰嗦几句:【 很多朋友听说webSocket不知道是什么。知道是什么不知道怎么用,知道怎么用不知道具体实现。其实我当初也是这样。...websocket需要服务器

    简单介绍一下tomcat的webSocketAPI使用:

    在这里啰嗦几句:

    很多朋友听说webSocket不知道是什么。知道是什么不知道怎么用,知道怎么用不知道具体实现。其实我当初也是这样。

    实际上webSocket可以简单的理解为用浏览器与服务器简历socket连接,但是用了一个特殊的协议,偶收协议,它与http协议发送的报头不一样。

    websocket需要服务器和浏览器支持,浏览器不支持,也就无法使用这个技术。服务器可以自己实现协议连接,但是我们不准备自己实现(其实看需求,至少对我来说不需要),当然目前javaEE官方不支持这个实现,没有规范(据说jsr356准备支持,期待来年【2013】javaEE7吧)

    目前实现的java服务端第三方webSocketAPI不算少,比如jetty就是一种(多的我也举例不了,我只知道,没研究过有多少实现。)tomcat也自带了实现API

    webSocket想要手动实现比较麻烦,可以看下tomcat实现过程,大致都一样。

    总之一句话,webSocket是一种客户端与服务端连接socket的技术,实现即时消息,取代comet但是并没广泛只用,因为大多需要浏览器的支持,相对comet有很多优点,此处不举例说明。可以自己google一下。

     

    tomcat7.027如何实现webSocket程序:

    总的来说,实现webSocket的servlet要继承WebSocketServlet这个类。这个类是tomcat自己包装的servlet。

    所有的入口都在protected StreamInbound createWebSocketInbound(String subProtocol) {}这个方法。 也就是说,我们实现这个方法,就可以实现握手协议了。

    注意看这个方法。 要求返回StreamInbound类型。这个类型我们需要继承自己实现。打开源码观看这个类

    有如下方法

     

    Java代码  收藏代码
    1. /** 
    2.     * Intended to be overridden by sub-classes that wish to be notified 
    3.     * when the outbound connection is established. The default implementation 
    4.     * is a NO-OP. 
    5.     * 
    6.     * @param outbound    The outbound WebSocket connection. 
    7.     */  
    8.    protected void onOpen(WsOutbound outbound) {  
    9.        // NO-OP  
    10.    }  
    11.   
    12.    /** 
    13.     * Intended to be overridden by sub-classes that wish to be notified 
    14.     * when the outbound connection is closed. The default implementation 
    15.     * is a NO-OP. 
    16.     * 
    17.     * @param status    The status code of the close reason. 
    18.     */  
    19.    protected void onClose(int status) {  
    20.        // NO-OP  
    21.    }  
    22.   
    23.   
    24.    /** 
    25.     * This method is called when there is a binary WebSocket message available 
    26.     * to process. The message is presented via a stream and may be formed from 
    27.     * one or more frames. The number of frames used to transmit the message is 
    28.     * not made visible to the application. 
    29.     * 
    30.     * @param is    The WebSocket message 
    31.     * 
    32.     * @throws IOException  If a problem occurs processing the message. Any 
    33.     *                      exception will trigger the closing of the WebSocket 
    34.     *                      connection. 
    35.     */  
    36.    protected abstract void onBinaryData(InputStream is) throws IOException;  
    37.   
    38.   
    39.    /** 
    40.     * This method is called when there is a textual WebSocket message available 
    41.     * to process. The message is presented via a reader and may be formed from 
    42.     * one or more frames. The number of frames used to transmit the message is 
    43.     * not made visible to the application. 
    44.     * 
    45.     * @param r     The WebSocket message 
    46.     * 
    47.     * @throws IOException  If a problem occurs processing the message. Any 
    48.     *                      exception will trigger the closing of the WebSocket 
    49.     *                      connection. 
    50.     */  
    51.    protected abstract void onTextData(Reader r) throws IOException;  

     

      上面的方法都是要我们自己实现的。tomcat没有给我们实现。

    仔细看都是onXxx格式,类似事件监听。其实也差不多。只是tomcat在得到消息或者链接发生变化的时候会去调用这些方法,实现方法“自动”触发。

    仔细看源码还有很多函数可以使用,这里不一一介绍。感兴趣可以打开源码看看。

    其实仔细看官方的例子,chat那个例子也能得到这个结论(tomcat的webSocket例子需要tomcat7.027才带有)

    我们定义一个servlet

     

    Java代码  收藏代码
    1. @WebServlet(urlPatterns = { "/chatWebSocket" })  
    2. public class ChatWebSocketServlet extends WebSocketServlet {  
    3.   
    4.     private static final long serialVersionUID = 1L;  
    5.     OnLineUser theUser;  
    6.   
    7.     @Override  
    8.     protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
    9.             throws ServletException, IOException {  
    10.         theUser = (OnLineUser) req.getSession().getAttribute("loginUser");  
    11.         super.doGet(req, resp);  
    12.     }  
    13.   
    14.     @Override  
    15.     protected StreamInbound createWebSocketInbound(String subProtocol) {  
    16.         return new ChatMessageInbound(theUser);  
    17.     }  
    18.   
    19. }  

     

     doget不用说,是连接的开始,然后取出登录的用户,这个是为了管理连接使用的,你在看这个例子的时候不需要doget方法和theUser声明,只要有createWebSocketInbound方法就行。上面说了。这个方法是webSocket的入口。其实也是WebSocketServlet这个类写好的doget,我们看WebSocketServlet的doget是如何写的

    Java代码  收藏代码
    1. @Override  
    2.    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
    3.            throws ServletException, IOException {  
    4.   
    5.        // Information required to send the server handshake message  
    6.        String key;  
    7.        String subProtocol = null;  
    8.        List<String> extensions = Collections.emptyList();  
    9.   
    10.        if (!headerContainsToken(req, "upgrade""websocket")) {  
    11.            resp.sendError(HttpServletResponse.SC_BAD_REQUEST);  
    12.            return;  
    13.        }  
    14.   
    15.        if (!headerContainsToken(req, "connection""upgrade")) {  
    16.            resp.sendError(HttpServletResponse.SC_BAD_REQUEST);  
    17.            return;  
    18.        }  
    19.   
    20.        if (!headerContainsToken(req, "sec-websocket-version""13")) {  
    21.            resp.setStatus(426);  
    22.            resp.setHeader("Sec-WebSocket-Version""13");  
    23.            return;  
    24.        }  
    25.   
    26.        key = req.getHeader("Sec-WebSocket-Key");  
    27.        if (key == null) {  
    28.            resp.sendError(HttpServletResponse.SC_BAD_REQUEST);  
    29.            return;  
    30.        }  
    31.   
    32.        String origin = req.getHeader("Origin");  
    33.        if (!verifyOrigin(origin)) {  
    34.            resp.sendError(HttpServletResponse.SC_FORBIDDEN);  
    35.            return;  
    36.        }  
    37.   
    38.        List<String> subProtocols = getTokensFromHeader(req,  
    39.                "Sec-WebSocket-Protocol-Client");  
    40.        if (!subProtocols.isEmpty()) {  
    41.            subProtocol = selectSubProtocol(subProtocols);  
    42.   
    43.        }  
    44.   
    45.        // TODO Read client handshake - Sec-WebSocket-Extensions  
    46.   
    47.        // TODO Extensions require the ability to specify something (API TBD)  
    48.        //      that can be passed to the Tomcat internals and process extension  
    49.        //      data present when the frame is fragmented.  
    50.   
    51.        // If we got this far, all is good. Accept the connection.  
    52.        resp.setHeader("upgrade""websocket");  
    53.        resp.setHeader("connection""upgrade");  
    54.        resp.setHeader("Sec-WebSocket-Accept", getWebSocketAccept(key));  
    55.        if (subProtocol != null) {  
    56.            resp.setHeader("Sec-WebSocket-Protocol", subProtocol);  
    57.        }  
    58.        if (!extensions.isEmpty()) {  
    59.            // TODO  
    60.        }  
    61.   
    62.        // Small hack until the Servlet API provides a way to do this.  
    63.        StreamInbound inbound = createWebSocketInbound(subProtocol);  
    64.        ((RequestFacade) req).doUpgrade(inbound);  
    65.    }  
     

    注意倒数第三行,调用了createWebSocketInbound方法,我们重写这个方法。

    Java代码  收藏代码
    1. @Override  
    2.     protected StreamInbound createWebSocketInbound(String subProtocol) {  
    3.         return new ChatMessageInbound(theUser);  
    4.     }  

    上面的ChatMessageInbound是我自己定义的继承类。

    Java代码  收藏代码
    1. public final class ChatMessageInbound extends MessageInbound {  
    2.   
    3.     public ChatMessageInbound(OnLineUser theUser) {  
    4.         this.theUser = theUser;  
    5.     }  
    6.   
    7.     @Override  
    8.     protected void onOpen(WsOutbound outbound) {  
    9.         // 添加链接到容器  
    10.         ChatMessageInbound theBound = this;  
    11.         ChatContainer.addInbound(theBound.theUser, theBound);  
    12.         // 向每个在线用户发送消息  
    13.         ChatContainer.eachAllBound(new ContainerCallBack() {  
    14.             @Override  
    15.             public void eachCallBack(ChatMessageInbound theBound, OnLineUser theUser) {  
    16.                 ListUserMsg listUserMsg = new ListUserMsg(ChatContainer.getUserList());  
    17.                 WriteTookit.writeToBound(theBound, listUserMsg.toMsg());  
    18.             }  
    19.         });  
    20.     }  
    21.   
    22.     @Override  
    23.     protected void onClose(int status) {  
    24.         ChatContainer.removeInbound(theUser);  
    25.     }  
    26.   
    27.     @Override  
    28.     protected void onBinaryMessage(ByteBuffer message) throws IOException {  
    29.     }  
    30.   
    31.     @Override  
    32.     protected void onTextMessage(CharBuffer message) throws IOException {  
    33. //      CHAT_MODEL.setMessage(message.toString());  
    34. //      ChatContainer.eachAllBound(new ContainerCallBack() {  
    35. //          @Override  
    36. //          public void eachCallBack(ChatMessageInbound theBound, OnLineUser theUser) {  
    37. //              WriteTookit.writeToBound(theBound, CHAT_MODEL.getSayMsg());  
    38. //          }  
    39. //      });  
    40.     }  
    41.   
    42.     // 变量区域  
    43.     private OnLineUser theUser;  
    44. }  

     这里只是简单实现了一下,注释部分只是处理这个方法的部分,那里是一个容器,存档所有在线用户。并且提供遍历插入以及删除等方法,在自己实现的时候完全不需要这么写。

    下面是容器代码

     

    Java代码  收藏代码
    1. public final class ChatContainer {  
    2.     /** 
    3.      * 保存服务器连接的用户的容器 
    4.      */  
    5.     private static final Map<OnLineUser, ChatMessageInbound> CHAT_MAP = new HashMap<OnLineUser, ChatMessageInbound>();  
    6.   
    7.     /** 
    8.      * 取出用户的连接 
    9.      */  
    10.     public static ChatMessageInbound getInbound(OnLineUser theUser) {  
    11.         return CHAT_MAP.get(theUser);  
    12.     }  
    13.   
    14.     /** 
    15.      * 放入一个连接 
    16.      */  
    17.     public static void addInbound(OnLineUser theUser,  
    18.             ChatMessageInbound outbound) {  
    19.         CHAT_MAP.put(theUser, outbound);  
    20.         System.out.println(CHAT_MAP.size());  
    21.     }  
    22.   
    23.     /** 
    24.      * 移除一个连接 
    25.      *  
    26.      * @param theUser 
    27.      * @return 
    28.      */  
    29.     public static ChatMessageInbound removeInbound(OnLineUser theUser) {  
    30.         return CHAT_MAP.remove(theUser);  
    31.     }  
    32.   
    33.     /** 
    34.      * 遍历所有连接 
    35.      */  
    36.     public static void eachAllBound(ContainerCallBack callBackInter) {  
    37.         Iterator<OnLineUser> keyIter = CHAT_MAP.keySet().iterator();  
    38.         while (keyIter.hasNext()) {  
    39.             OnLineUser theUser = keyIter.next();  
    40.             callBackInter.eachCallBack(CHAT_MAP.get(theUser), theUser);  
    41.         }  
    42.     }  
    43.   
    44.     /** 
    45.      * 回调函数的接口 
    46.      *  
    47.      * @author WangZhenChong 
    48.      */  
    49.     public interface ContainerCallBack {  
    50.         void eachCallBack(ChatMessageInbound theBound, OnLineUser theUser);  
    51.     }  
    52.   
    53. }  

     

     

    我定义了一种数据交约定,使用json 字符串,MsgType表示消息类型,类似windows的消息机制

    Java代码  收藏代码
    1. /** 
    2.  * 前台和后台交互的信息类型常量 
    3.  *  
    4.  * @author WangZhenChong 
    5.  *  
    6.  */  
    7. public final class MsgTypeConstants {  
    8.     public static short GET_USER_LIST = 1;// 在线所有用户信息交互  
    9.     public static short SEND_ONE_TO_ONE = 2;// 对一个用户发送消息  
    10.     public static short SEND_ONE_TO_ALL = 3;// 对所有用户发送消息  
    11.     public static short SEND_SERVER_MSG = 4;// 发送系统消息  
    12. }  

     余下的msgContent就是消息内容,比如列出现在用户这个内容就是[...,...,...,...]发送消息就是消息模型的内容。

    这样解决单通道多操作的方法。

     

     

    下面列出前台js核心内容。

    使用jquery

    Js代码  收藏代码
    1. $(document).ready(function() {  
    2.     $("#connBtn").bind('click'function() {  
    3.         $.ajax({  
    4.             url : "/tomcatWebSocket/Login#?asdasdasd",  
    5.             type : "POST",  
    6.             processData : false,  
    7.             data : $.param({  
    8.                         username : document.getElementById("usernameField").value  
    9.                     }),  
    10.             success : function(msg, status) {  
    11.                 initChat();  
    12.                 initUserList();  
    13.                 $("#sendBtn").removeAttr("disabled");  
    14.                 $("#connBtn").attr("disabled""disabled");  
    15.                 $("#usernameField").attr("disabled""disabled");  
    16.             },  
    17.             error : function(jqXHR, textStatus, errorThrown) {  
    18.                 alert("服务器内部错误");  
    19.             }  
    20.         });  
    21.   
    22.     });  
    23.       
    24.   
    25. var Chat = {};  
    26. Chat.socket = null;  
    27. function initChat() {  
    28.     var wsURL = 'ws://' + window.location.host  
    29.             + '/tomcatWebSocket/chatWebSocket';  
    30.     if ('WebSocket' in window) {  
    31.         Chat.socket = new WebSocket(wsURL);  
    32.     } else if ('MozWebSocket' in window) {  
    33.         Chat.socket = new MozWebSocket(wsURL);  
    34.     } else {  
    35.         alert("浏览器不支持");  
    36.         return false;  
    37.     }  
    38.   
    39.     Chat.socket.onopen = function() {  
    40.     };  
    41.   
    42.     Chat.socket.onclose = function() {  
    43.         Chat.writeToConsole("断开连接了 ");  
    44.         initChat();  
    45.     };  
    46.     Chat.socket.onmessage = function(message) {  
    47.         if (typeof message.data == "string") {// 如果发送的是字符串信息.  
    48.             var msgObj = eval("(" + message.data + ")");  
    49.             switch (msgObj.MsgType) {  
    50.                 case MsgTypeConstants.GET_USER_LIST :// 所有用户信息  
    51.                     Chat.preUserList(msgObj.userList);  
    52.                     break;  
    53.                 case MsgTypeConstants.SEND_ONE_TO_ALL :  
    54.                     Chat.writeToConsole(msgObj.msgContext);  
    55.                     break;  
    56.                 default :  
    57.                     alert("未知错误,请刷新页面");  
    58.             }  
    59.   
    60.         }  
    61.   
    62.     };  
    63.   
    64.     Chat.sendMessage = function() {  
    65.         Chat.socket.send(ueditor.getContentTxt());  
    66.     };  
    67. }  
    68.   
    69. Chat.writeToConsole = function(message) {  
    70. <span style="white-space: pre;">    </span>//往控制台打印得到的聊天消息  
    71. };  
    72.   
    73. /** 
    74.  * 处理刷新用户信息的方法。 
    75.  */  
    76. Chat.preUserList = function(userList) {  
    77.     //用户信息列表  
    78.   
    79. };  

     这些代码只是参考内容,实际上不可能拷贝下来直接运行,


    展开全文
  • 看了上面链接的同学肯定对过去怎么低效率高消耗(轮询或comet)的做此事已经有所了解了,而在websocket API,浏览器和服务器只需要要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接...

    什么是websocket

    WebSocket 协议是html5引入的一种新的协议,其目的在于实现了浏览器与服务器全双工通信。看了上面链接的同学肯定对过去怎么低效率高消耗(轮询或comet)的做此事已经有所了解了,而在websocket API,浏览器和服务器只需要要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。同时这么做有两个好处

    1.通信传输字节减少:比起以前使用http传输数据,websocket传输的额外信息很少,据百度说只有2k

    2.服务器可以主动向客户端推送消息,而不用客户端去查询

    关于概念和好处,网上到处都是,不再赘述,简单看看其原理,然后动手写一个web版聊天室吧

    握手

    除了TCP连接的三次握手,websocket协议中客户端与服务器想建立连接需要一次额外的握手动作,在最新版的协议中是这个样子的

    客户端向服务器发送请求

    复制代码代码如下:

    GET / HTTP/1.1

    Upgrade: websocket

    Connection: Upgrade

    Host: 127.0.0.1:8080

    Origin: http://test.com

    Pragma: no-cache

    Cache-Control: no-cache

    Sec-WebSocket-Key: OtZtd55qBhJF2XLNDRgUMg==

    Sec-WebSocket-Version: 13

    Sec-WebSocket-Extensions: x-webkit-deflate-frame

    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36

    服务器给出响应

    复制代码代码如下:

    HTTP/1.1 101 Switching Protocols

    Upgrade: websocket

    Connection: Upgrade

    Sec-WebSocket-Accept: xsOSgr30aKL2GNZKNHKmeT1qYjA=

    在请求中的“Sec-WebSocket-Key”是随机的,服务器端会用这些数据来构造出一个SHA-1的信息摘要。把“Sec-WebSocket-Key”加上一个魔幻字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”。使用 SHA-1 加密,之后进行 BASE-64编码,将结果做为 “Sec-WebSocket-Accept” 头的值,返回给客户端(来自维基百科)。

    websocket API

    经过握手之后浏览器与服务器建立连接,两者就可以互相通信了。websocket的API真心很简单,看看W3C的定义

    复制代码代码如下:

    enum BinaryType { "blob", "arraybuffer" };

    [Constructor(DOMString url, optional (DOMString or DOMString[]) protocols)]

    interface WebSocket : EventTarget {

    readonly attribute DOMString url;

    // ready state

    const unsigned short CONNECTING = 0;

    const unsigned short OPEN = 1;

    const unsigned short CLOSING = 2;

    const unsigned short CLOSED = 3;

    readonly attribute unsigned short readyState;

    readonly attribute unsigned long bufferedAmount;

    // networking

    attribute EventHandler onopen;

    attribute EventHandler onerror;

    attribute EventHandler onclose;

    readonly attribute DOMString extensions;

    readonly attribute DOMString protocol;

    void close([Clamp] optional unsigned short code, optional DOMString reason);

    // messaging

    attribute EventHandler onmessage;

    attribute BinaryType binaryType;

    void send(DOMString data);

    void send(Blob data);

    void send(ArrayBuffer data);

    void send(ArrayBufferView data);

    };

    创建websocket

    复制代码代码如下:

    ws=new WebSocket(address); //ws://127.0.0.1:8080

    调用其构造函数,传入地址,就可以创建一个websocket了,值得注意的是地址协议得是ws/wss

    关闭socket

    复制代码代码如下:

    ws.close();

    调用webservice实例的close()方法就可以关闭webservice,当然也可以传入一个code和string说明为什么关了

    几个回调函数句柄

    由于其异步执行,回调函数自然少不了,有四个重要的

    onopen:连接创建后调用

    onmessage:接收到服务器消息后调用

    onerror:出错时调用

    onclose:关闭连接的时候调用

    看名字就知道是干什么的了,每个回调函数都会传入一个Event对象,可以通过event.data访问消息

    使用API

    我们可以在创建socket成功后为其回调函数赋值

    复制代码代码如下:

    ws=new WebSocket(address);

    ws.onopen=function(e){

    var msg=document.createElement('div');

    msg.style.color='#0f0';

    msg.innerHTML="Server > connection open.";

    msgContainer.appendChild(msg);

    ws.send('{}');

    也可以通过事件绑定的方式

    复制代码代码如下:

    ws=new WebSocket(address);

    ws.addEventListener('open',function(e){

    var msg=document.createElement('div');

    msg.style.color='#0f0';

    msg.innerHTML="Server > connection open.";

    msgContainer.appendChild(msg);

    ws.send('{}');

    客户端实现

    其实客户端的实现比较简单,除了websocket相关的几句就是一些自动focus、回车键事件处理、消息框自动定位到底部等简单功能,不一一说明了

    展开全文
  • 简单介绍一下tomcat的webSocketAPI使用: 在这里啰嗦几句:【 很多朋友听说webSocket不知道是什么。知道是什么不知道怎么用,知道怎么用不知道具体实现。...websocket需要服务器和浏览器支持,浏...
  • 参考了http://blog.chenzuhuang.com/archive/28.html 的代码,成功利用Tomcat8搭建了JSR356标准的WebSocket服务器,HTML的客户端也成功实现了,但是我想写一个Android平台下的客户端,请问 ``` //判断当前...
  • 上一笔记说道 想要连接远程服务器,需要一个新的websocket实例,并且需要为websocket提供一个URL,上一笔记最后的模拟到的小例子用到是 不是自己的URL。 此次介绍,在本地搭建一个server。 首先搭建本地的 ...
  • 前言 上一次进行了手动交换sdp成功进行了ice连接,但是正常情况下,不可能是让你手动...服务器搭建 首先初始化个npm项目,安装ws 起个ws到8001 const webSocket = require("ws"); const wss = new webSocket.Server
  • 那么如果在Netty中使用WebSocket进行长连接通信要怎么实现。 WebSocket 现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请
  • 那么如果在Netty中使用WebSocket进行长连接通信要怎么实现。WebSocket现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器...
  • github.com/gorilla/websocket BSD 2-Clause "Simplified" License github.com/hashicorp/golang-lru Mozilla Public License 2.0 github.com/hashicorp/hcl Mozilla Public License 2.0 github....
  • socket.IO是一个websocket库...使用socket.io和nodejs搭建websocket服务器端 socket.io不仅可以搭建客户端的websocket服务,而且支持nodejs服务器端的websocket。 下面让我来介绍一下怎么安装配置nodejs. 进入http:
  • 使用socket.io和nodejs搭建websocket服务器端 socket.io不仅可以搭建客户端的websocket服务,而且支持nodejs服务器端的websocket。 下面让我来介绍一下怎么安装配置nodejs. 进入http://nodejs.org/#download下载msi...
  • 以前的文章中《PHP微信墙制作,开源》已经用PHP搭建了一个微信墙获取信息的服务器,然后我就在想推送技术应该怎么解决,上一篇已经用了.NET 的signalr做了一个微信墙,PHP一直没什么好思路,本来想用websocket,但...
  • 随便你怎么拆分服务器。只需要修改极少的代码就可以进行拆分。不同的server挂上不同的组件就行了嘛! 3.跨平台的分布式服务端 ET框架使用C#做服务端,现在C#是完全可以跨平台的,在linux上安装.netcore,即可,不...
  • Web上选择了无所不能的JavaScript,在教程中将会演示其在网页开发、小程序开发、桌面应用开发、服务器后端服务开发。 整个教程里,推荐先用后学,先把项目跑起来看看效果,再按需学习相关知识,直到自己能把项目写...
  • 2009 年选择了 GAE 作为服务器,并开始实现 Latke 框架来解决跨云平台,直到告别 GAE,不得不感叹技术更迭之快 感受到了自造轮子的优缺点,并且可以肯定一点:对于一个想要长久的产品来说,自制技术框架优势远大于...
  • 手把手教你怎么使用云服务器 带你了解什么是Push消息推送 人在家中坐,班从天上来「小程序推送」 Java发送邮件时,必须要的一个配置! fastjson学习笔记 本地文件自动同步到GitHub 为什么PUSH推送经常出事故? 三歪...

空空如也

空空如也

1 2
收藏数 22
精华内容 8
关键字:

websocket服务器怎么搭建