青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Fork me on GitHub
隨筆 - 215  文章 - 13  trackbacks - 0
<2017年1月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234


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

常用鏈接

留言簿(1)

隨筆分類

隨筆檔案

相冊

Awesome

Blog

Book

GitHub

Link

搜索

  •  

積分與排名

  • 積分 - 219730
  • 排名 - 117

最新評論

閱讀排行榜

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 思月行云 閱讀(784) 評論(0)  編輯 收藏 引用 所屬分類: Erlang
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久精品在线| 欧美色欧美亚洲另类二区| 欧美高清在线视频| 欧美成人四级电影| 狠狠噜噜久久| 欧美成人中文字幕在线| 久久蜜桃资源一区二区老牛 | 久久精品国产99国产精品| 欧美一区二区国产| 久久一本综合频道| 欧美伊人影院| 一本综合精品| 久久综合伊人77777蜜臀| 久热精品在线| 在线亚洲伦理| 亚洲视频在线看| 久久全国免费视频| 91久久精品国产91久久| 亚洲久久成人| 久久久99久久精品女同性| 欧美日本中文字幕| 国产一区二区三区在线观看免费 | 91久久中文| 一区二区三区精密机械公司| 噜噜噜在线观看免费视频日韩| 美女视频一区免费观看| 欧美日韩精品一区| 国产一区二区三区高清| 亚洲国产二区| 亚洲欧美国产日韩天堂区| 久久男女视频| 一区二区三区高清不卡| 久久丁香综合五月国产三级网站| 欧美激情精品久久久久久黑人| 国产精品一区二区久久久久| 亚洲黄色精品| 久久国产精品毛片| 亚洲看片网站| 亚洲午夜国产一区99re久久| 国产亚洲欧美日韩美女| 日韩亚洲欧美一区| 久久青草欧美一区二区三区| 99精品视频免费在线观看| 久久女同互慰一区二区三区| 国产精品日韩欧美一区| 99re8这里有精品热视频免费| 久久免费视频一区| 亚洲制服av| 欧美调教视频| 99精品久久久| 欧美激情欧美狂野欧美精品| 午夜精品久久久久久久久久久久久 | 永久免费精品影视网站| 亚洲自拍偷拍麻豆| 亚洲人成啪啪网站| 久久精品夜色噜噜亚洲aⅴ| 国产精品日本精品| 一本色道久久精品| 亚洲激情精品| 欧美大胆人体视频| 亚洲欧洲精品一区二区三区| 久久深夜福利| 久久激情综合| 国产在线一区二区三区四区 | 午夜精品美女自拍福到在线 | 国产精品视频xxxx| 这里只有精品丝袜| 在线播放一区| 老牛影视一区二区三区| 午夜精品视频在线| 精品不卡视频| 欧美福利视频| 欧美激情国产高清| 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 99爱精品视频| 欧美国产精品劲爆| 欧美成人性网| 亚洲午夜精品久久久久久app| 99re这里只有精品6| 欧美日韩一区精品| 欧美一区二区视频免费观看| 性色av一区二区三区在线观看| 国产在线精品成人一区二区三区| 久久野战av| 欧美激情亚洲自拍| 午夜精品美女自拍福到在线| 欧美一区久久| 9久草视频在线视频精品| 一本色道久久综合亚洲精品婷婷 | 久久久噜噜噜久久狠狠50岁| 国模精品一区二区三区色天香| 久久五月天婷婷| 欧美高清在线一区二区| 亚洲天堂成人| 久久午夜国产精品| 亚洲午夜电影网| 久久综合影视| 欧美伊久线香蕉线新在线| 久久久欧美一区二区| 夜夜爽99久久国产综合精品女不卡| 一区二区三区国产盗摄| 国内精品模特av私拍在线观看| 亚洲国产合集| 国产欧美亚洲精品| 亚洲精品在线一区二区| 农夫在线精品视频免费观看| 欧美日韩精品系列| 亚洲国产高清aⅴ视频| 欧美精品粉嫩高潮一区二区 | 欧美午夜精品久久久久久浪潮| 欧美在线不卡| 欧美精品在线免费观看| 久久一区二区三区四区| 国产精品国产a级| 亚洲国产日韩在线| 黄色成人在线网址| 亚洲欧美激情四射在线日 | 91久久精品国产| 亚洲视频视频在线| 亚洲精选视频在线| 久久综合久色欧美综合狠狠| 亚洲欧美另类国产| 欧美国产日产韩国视频| 久久婷婷麻豆| 国户精品久久久久久久久久久不卡| 在线视频你懂得一区二区三区| 亚洲日本欧美日韩高观看| 久久久久成人精品免费播放动漫| 午夜老司机精品| 国产精品免费小视频| 一区二区欧美国产| 一区二区三区蜜桃网| 欧美国产日本在线| 亚洲欧洲精品一区二区三区| 亚洲高清视频在线| 久久经典综合| 久久久久一区二区三区| 黄色在线成人| 亚洲激情综合| 亚洲美女在线国产| 欧美成人精品在线播放| 午夜精品久久久久久久久| 久久久99精品免费观看不卡| 欧美日韩在线播放| 亚洲精品一区二区三区四区高清 | 一本久久综合亚洲鲁鲁| 欧美aaa级| 亚洲日本中文字幕| 一区二区三区不卡视频在线观看| 欧美精品在线网站| 亚洲视频观看| 久久久久久亚洲精品中文字幕| 国产日韩欧美综合精品| 久久精品视频va| 亚洲国产精品成人久久综合一区 | 久久久噜噜噜久久中文字幕色伊伊 | 午夜精品久久| 免费成人高清视频| 一区二区电影免费观看| 欧美三级乱人伦电影| 亚洲欧美在线x视频| 久久久免费精品视频| 在线欧美不卡| 欧美日韩hd| 亚洲欧美日韩另类| 免费在线成人av| 亚洲香蕉伊综合在人在线视看| 国产精品久久久久久久久婷婷| 久久er精品视频| 亚洲黄色片网站| 亚洲欧美一区二区三区在线| 国产日韩欧美一区在线 | 国产精品每日更新| 久久久久久一区二区| 99精品久久久| 美女免费视频一区| 亚洲午夜精品| 1024成人网色www| 欧美午夜不卡在线观看免费| 久久久国产精品一区| 一本色道久久综合亚洲精品不| 久久久综合网| 亚洲欧美不卡| 亚洲精品日韩久久| 国产日韩欧美日韩| 欧美日韩亚洲综合一区| 久久午夜国产精品| 亚洲欧美日韩综合aⅴ视频| 亚洲第一黄网| 麻豆久久精品| 久久久久国内| 午夜国产不卡在线观看视频| 亚洲国产欧美日韩| 国产免费成人在线视频| 欧美高清在线视频| 久久天堂成人| 久久精品欧美日韩| 欧美亚洲视频一区二区| 国产精品99久久久久久人 | 久久亚洲二区|