• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Fork me on GitHub
            隨筆 - 215  文章 - 13  trackbacks - 0
            <2016年1月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456


            專注即時通訊及網游服務端編程
            ------------------------------------
            Openresty 官方模塊
            Openresty 標準模塊(Opm)
            Openresty 三方模塊
            ------------------------------------
            本博收藏大部分文章為轉載,并在文章開頭給出了原文出處,如有再轉,敬請保留相關信息,這是大家對原創作者勞動成果的自覺尊重!!如為您帶來不便,請于本博下留言,謝謝配合。

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            相冊

            Awesome

            Blog

            Book

            GitHub

            Link

            搜索

            •  

            積分與排名

            • 積分 - 216749
            • 排名 - 118

            最新評論

            閱讀排行榜

            erlang實現websocket簡單示例

             

            本示例僅支持文本消息

            基于websocket版本13
             
            由于joe armstrong的例子:
             
            http://armstrongonsoftware.blogspot.com/2009/12/comet-is-dead-long-live-websockets.html

            已經過時,不符合現在的websocket標準,于是改寫了一下

             
             
            還參考了cowboy的代碼:
             
            https://github.com/extend/cowboy
             
            websocket標準參考:
            http://blog.csdn.net/fenglibing/article/details/6852497
             
             

            后端代碼:
            復制代碼
              1 -module(local_server).
              2 -export([start/0]).
              3 
              4 start() ->
              5     F = fun interact/2,
              6     spawn(fun() -> start(F, 0) end).
              7 
              8 start(F, State0) ->
              9     {ok, Listen} = gen_tcp:listen(8000, [{packet,raw}, {reuseaddr,true}, {active, true}]),
             10     par_connect(Listen, F, State0).
             11 
             12 par_connect(Listen, F, State0) ->
             13     case gen_tcp:accept(Listen) of
             14         {ok, Socket} ->
             15             spawn(fun() -> par_connect(Listen, F, State0) end),
             16             wait(Socket, F, State0);
             17         {error, closed} ->
             18             {ok, Listen2} = gen_tcp:listen(8000, [{packet,raw}, {reuseaddr,true}, {active, true}]),
             19             par_connect(Listen2, F, State0)
             20     end.
             21 
             22 wait(Socket, F, State0) ->
             23     receive
             24         {tcp, Socket, Data} ->
             25             Key = list_to_binary(lists:last(string:tokens(hd(lists:filter(fun(S) -> lists:prefix("Sec-WebSocket-Key:", S) end, string:tokens(Data, "\r\n"))), ": "))),
             26             Challenge = base64:encode(crypto:sha(<< Key/binary, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" >>)),
             27             Handshake =
             28             ["HTTP/1.1 101 Switching Protocols\r\n",
             29              "connection: Upgrade\r\n",
             30              "upgrade: websocket\r\n",
             31              "sec-websocket-accept: ", Challenge, "\r\n",
             32              "\r\n",<<>>],
             33             gen_tcp:send(Socket, Handshake),
             34             send_data(Socket, "Hello, my world"),
             35             S = self(),
             36             Pid = spawn_link(fun() -> F(S, State0) end),
             37             loop(Socket, Pid);
             38         _Any ->
             39             wait(Socket, F, State0)
             40     end.
             41 
             42 loop(Socket, Pid) ->
             43     receive
             44         {tcp, Socket, Data} ->
             45             Text = websocket_data(Data),
             46             case Text =/= <<>> of
             47                 true ->
             48                     Pid ! {browser, self(), ["You said: ",  Text]};
             49                 false ->
             50                     ok
             51             end,
             52             loop(Socket, Pid);
             53         {tcp_closed, Socket} ->
             54             ok;
             55         {send, Data} ->
             56             send_data(Socket, Data),
             57             loop(Socket, Pid);
             58         _Any ->
             59             loop(Socket, Pid)
             60     end.
             61 
             62 interact(Browser, State) ->
             63     receive
             64         {browser, Browser, Str} ->
             65             Browser ! {send, Str},
             66             interact(Browser, State)
             67     after 1000 ->
             68             Browser ! {send, "clock ! tick " ++ integer_to_list(State)},
             69             interact(Browser, State+1)
             70     end.
             71 
             72 %% 僅處理長度為125以內的文本消息
             73 websocket_data(Data) when is_list(Data) ->
             74     websocket_data(list_to_binary(Data));
             75 websocket_data(<< 1:1, 0:3, 1:4, 1:1, Len:7, MaskKey:32, Rest/bits >>) when Len < 126 ->
             76     <<End:Len/binary, _/bits>> = Rest,
             77     Text = websocket_unmask(End, MaskKey, <<>>),
             78     Text;
             79 websocket_data(_) ->
             80     <<>>. 
             81 
             82 %% 由于Browser發過來的數據都是mask的,所以需要unmask
             83 websocket_unmask(<<>>, _, Unmasked) ->
             84     Unmasked;
             85 websocket_unmask(<< O:32, Rest/bits >>, MaskKey, Acc) ->
             86     T = O bxor MaskKey,
             87     websocket_unmask(Rest, MaskKey, << Acc/binary, T:32 >>);
             88 websocket_unmask(<< O:24 >>, MaskKey, Acc) ->
             89     << MaskKey2:24, _:8 >> = << MaskKey:32 >>,
             90     T = O bxor MaskKey2,
             91     << Acc/binary, T:24 >>;
             92 websocket_unmask(<< O:16 >>, MaskKey, Acc) ->
             93     << MaskKey2:16, _:16 >> = << MaskKey:32 >>,
             94     T = O bxor MaskKey2,
             95     << Acc/binary, T:16 >>;
             96 websocket_unmask(<< O:8 >>, MaskKey, Acc) ->
             97     << MaskKey2:8, _:24 >> = << MaskKey:32 >>,
             98     T = O bxor MaskKey2,
             99     << Acc/binary, T:8 >>.
            100 
            101 %% 發送文本給Client
            102 send_data(Socket, Payload) ->
            103     Len = iolist_size(Payload),
            104     BinLen = payload_length_to_binary(Len),
            105     gen_tcp:send(Socket, [<< 1:1, 0:3, 1:4, 0:1, BinLen/bits >>, Payload]).
            106 
            107 payload_length_to_binary(N) ->
            108     case N of
            109         N when N =< 125 -> << N:7 >>;
            110         N when N =< 16#ffff -> << 126:7, N:16 >>;
            111         N when N =< 16#7fffffffffffffff -> << 127:7, N:64 >>
            112     end.
            復制代碼

            前端使用js發送websocket請求

            復制代碼
              1 <html>
              2   <head>
              3     <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
              4     <title>Websocket client</title>
              5     <script src="jquery.min.js"></script>
              6     <script type="text/javascript">
              7       
              8       var websocket;
              9       $(document).ready(init);
             10       
             11       function init() {
             12           if(!("WebSocket" in window)){  
             13               $('#status').append('<p><span style="color: red;">websockets are not supported </span></p>');
             14               $("#navigation").hide();  
             15           } else {
             16               $('#status').append('<p><span style="color: green;">websockets are supported </span></p>');
             17               connect();
             18           };
             19               $("#connected").hide();     
             20               $("#content").hide();     
             21       };
             22 
             23       function connect()
             24       {
             25           showScreen('<span style="color: red;">CONNECTING </span>');
             26           wsHost = $("#server").val()
             27           websocket = new WebSocket(wsHost);
             28           showScreen('<b>Connecting to: ' +  wsHost + '</b>'); 
             29           websocket.onopen = function(evt) { onOpen(evt) }; 
             30           websocket.onclose = function(evt) { onClose(evt) }; 
             31           websocket.onmessage = function(evt) { onMessage(evt) }; 
             32           websocket.onerror = function(evt) { onError(evt) }; 
             33       };  
             34       
             35       function disconnect() {
             36           websocket.close();
             37       }; 
             38 
             39       function toggle_connection(){
             40           if(websocket.readyState == websocket.OPEN){
             41               disconnect();
             42           } else {
             43               connect();
             44           };
             45       };
             46 
             47       function sendTxt() {
             48           if(websocket.readyState == websocket.OPEN){
             49               txt = $("#send_txt").val();
             50               websocket.send(txt);
             51               showScreen('sending: ' + txt); 
             52           } else {
             53                showScreen('websocket is not connected'); 
             54           };
             55       };
             56 
             57       function onOpen(evt) { 
             58           showScreen('<span style="color: green;">CONNECTED </span>'); 
             59           $("#connected").fadeIn('slow');
             60           $("#content").fadeIn('slow');
             61       };  
             62 
             63       function onClose(evt) { 
             64           showScreen('<span style="color: red;">DISCONNECTED </span>');
             65       };  
             66 
             67       function onMessage(evt) { 
             68           showScreen('<span style="color: blue;">RESPONSE: ' + evt.data+ '</span>'); 
             69       };  
             70 
             71       function onError(evt) {
             72           showScreen('<span style="color: red;">ERROR: ' + evt.data+ '</span>');
             73       };
             74 
             75       function showScreen(txt) { 
             76           $('#output').prepend('<p>' + txt + '</p>');
             77       };
             78 
             79       function clearScreen() 
             80       { 
             81           $('#output').html("");
             82       };
             83     </script>
             84   </head>
             85 
             86   <body>
             87     <div id="header">
             88       <h1>Websocket client</h1>
             89       <div id="status"></div>
             90     </div>
             91 
             92 
             93     <div id="navigation">
             94 
             95       <p id="connecting">
             96     <input type='text' id="server" value="ws://localhost:8000/websocket"></input>
             97     <button type="button" onclick="toggle_connection()">connection</button>
             98       </p>
             99       <div id="connected">                
            100     <p>
            101       <input type='text' id="send_txt" value=></input>
            102       <button type="button" onclick="sendTxt();">send</button>
            103     </p>
            104       </div>
            105 
            106       <div id="content">                        
            107     <button id="clear" onclick="clearScreen()" >Clear text</button>
            108     <div id="output"></div>
            109       </div>
            110 
            111     </div>
            112   </body>
            113 </html> 
            復制代碼

             

            附件(內含上文代碼及jquery和erlang編譯后的beam文件)下載地址:

            http://files.cnblogs.com/suex/websocket_demo.zip 

            在解壓后的文件夾中啟動erlang shell, 執行local_server:start()即可啟動服務端,

            此時打開index.html即可看到文首的截圖效果

            posted on 2017-01-06 10:37 思月行云 閱讀(770) 評論(0)  編輯 收藏 引用 所屬分類: Erlang
            久久伊人色| 亚洲人成无码网站久久99热国产| 久久婷婷午色综合夜啪| 亚洲人成网站999久久久综合 | 久久免费精品一区二区| 97久久久久人妻精品专区| 久久久久亚洲精品天堂| 久久99精品久久久久久齐齐| 日韩精品久久久久久久电影| 久久精品国产亚洲AV无码麻豆 | 麻豆AV一区二区三区久久 | 久久国产欧美日韩精品| 99久久99久久精品国产片果冻| 精品水蜜桃久久久久久久| 久久亚洲AV无码精品色午夜麻豆 | 国内精品伊人久久久久| 四虎亚洲国产成人久久精品| 久久精品国产99久久无毒不卡 | 久久天天躁狠狠躁夜夜avapp| 狠狠久久综合伊人不卡| 久久久精品人妻一区二区三区四| 日本精品久久久久久久久免费| 色婷婷综合久久久久中文 | 久久免费的精品国产V∧| 久久夜色精品国产亚洲av| 国内精品久久人妻互换| 久久精品国产亚洲av麻豆蜜芽| 99久久国产综合精品网成人影院 | 亚洲精品97久久中文字幕无码| 精品999久久久久久中文字幕| 伊人久久无码中文字幕| 亚洲天堂久久久| 蜜臀久久99精品久久久久久| 国产精品久久久久久久久久免费| 久久精品中文闷骚内射| 亚洲精品乱码久久久久66| 亚洲欧美久久久久9999| 日韩精品无码久久一区二区三| 99久久国产综合精品网成人影院 | 国产精品久久久久国产A级| 亚洲午夜久久久久久噜噜噜|