Erlang通过WebSocket和浏览器交互
来源:互联网 发布:提升视频画质软件 编辑:程序博客网 时间:2024/06/05 01:02
本文是用Erlang通过WebSocket协议实现的一个简单的服务器端的double计算器,Erlang下面有成熟的Web框架Cowboy,但本着了解原理的心态没有用这个框架,代码如下:
<!DOCTYPE html><html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Erlang & WebSocket</title> <script type="text/javascript"> function doubleNum() { var o = document.getElementById("number"); var socket = new WebSocket("ws://127.0.0.1:8181"); socket.onopen = function() { socket.send(o.value); socket.onmessage = function(r) { o.value = r.data; socket.close(); socket=null; } } } </script> </head> <body> <input type="text" size=10 value=100 id="number"> <input type="button" value="Double" onclick="doubleNum()"> </body></html>
-module(clock_demo).-export([start/0]).start() -> case gen_tcp:listen(8181, [binary,{packet,0},{active,true},{reuseaddr,true},{packet_size,1024*2},{keepalive,true}]) of {ok,Listen} -> spawn(fun()->par_connect(Listen) end); _Err -> io:format("Accept failed:~w~n", [_Err]) end.par_connect(Listen) -> {ok,Socket} = gen_tcp:accept(Listen), spawn(fun()->par_connect(Listen) end), wait(Socket).wait(Socket) -> receive {tcp,Socket,Bin} -> gen_tcp:send(Socket, list_to_binary(handshake(Bin))), loop(Socket); Any -> io:format("Received(2): ~p~n",[Any]), wait(Socket) end.loop(Socket) -> receive {tcp,Socket,Data} -> %% 打印Brorser发送上来的数据 io:format("Received(3): ~s~n",[websocket_data(Data)]), %% 向Brorser发送数据 gen_tcp:send(Socket, [build_client_data( integer_to_binary(binary_to_integer(websocket_data(Data))*2 ))]), loop(Socket); Any -> io:format("Received(4): ~p~n", [Any]), loop(Socket) end.handshake(Bin) -> Key = list_to_binary(lists:last(string:tokens(hd(lists:filter(fun(S) -> lists:prefix("Sec-WebSocket-Key:", S) end, string:tokens(binary_to_list(Bin), "\r\n"))), ": "))), Accept = base64:encode(crypto:hash(sha,<< Key/binary, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" >>)), %%{ok, Write_log} = file:open("D:/Erlang/erlang_log",[append]), %%io:format(Write_log, "Accept: ~s~n", [Accept]), [ "HTTP/1.1 101 Switching Protocols\r\n", "connection: Upgrade\r\n", "upgrade: websocket\r\n", "Blog: http://blog.csdn.net/jom_ch\r\n", "sec-websocket-accept: ", Accept, "\r\n", "\r\n" ].%% 仅处理长度为125以内的文本消息websocket_data(Data) when is_list(Data) -> websocket_data(list_to_binary(Data));websocket_data(<< 1:1, 0:3, 1:4, 1:1, Len:7, MaskKey:32, Rest/bits >>) when Len < 126 -> <<End:Len/binary, _/bits>> = Rest, Text = websocket_unmask(End, MaskKey, <<>>), Text;websocket_data(_) -> <<>>. %% 由于Browser发过来的数据都是mask的,所以需要unmaskwebsocket_unmask(<<>>, _, Unmasked) -> Unmasked;websocket_unmask(<< O:32, Rest/bits >>, MaskKey, Acc) -> T = O bxor MaskKey, websocket_unmask(Rest, MaskKey, << Acc/binary, T:32 >>);websocket_unmask(<< O:24 >>, MaskKey, Acc) -> << MaskKey2:24, _:8 >> = << MaskKey:32 >>, T = O bxor MaskKey2, << Acc/binary, T:24 >>;websocket_unmask(<< O:16 >>, MaskKey, Acc) -> << MaskKey2:16, _:16 >> = << MaskKey:32 >>, T = O bxor MaskKey2, << Acc/binary, T:16 >>;websocket_unmask(<< O:8 >>, MaskKey, Acc) -> << MaskKey2:8, _:24 >> = << MaskKey:32 >>, T = O bxor MaskKey2, << Acc/binary, T:8 >>.%% 发送文本给Clientbuild_client_data(Data) -> Len = iolist_size(Data), BinLen = payload_length_to_binary(Len), [<< 1:1, 0:3, 1:4, 0:1, BinLen/bits >>, Data].payload_length_to_binary(N) -> case N of N when N =< 125 -> << N:7 >>; N when N =< 16#ffff -> << 126:7, N:16 >>; N when N =< 16#7fffffffffffffff -> << 127:7, N:64 >> end.
参考:http://www.cnblogs.com/suex/p/3669953.html
0 0
- Erlang通过WebSocket和浏览器交互
- 用websocket和erlang通讯
- 通过websocket 实现与容器的交互
- erlang和外围程序的交互
- Erlang和其他语言的交互
- Erlang中通过Port与外部程序交互
- Erlang cowboy websocket 服务器
- 如何通过浏览器分析前后端交互
- Silverlight和浏览器交互(1)
- Silverlight和浏览器交互介绍
- 如何使用Erlang port 和外部程序交互
- erlang实现websocket简单示例
- SocketLog-微信调试、API调试和AJAX的调试的工具,能将日志通过WebSocket输出到Chrome浏览器的console中
- SocketLog-微信调试、API调试和AJAX的调试的工具,能将日志通过WebSocket输出到Chrome浏览器的console中
- 【ASP.net】浏览器和服务器的交互
- 浏览器和服务器之间的交互
- 浏览器和服务器的交互简单原理
- 浏览器和服务器的交互过程
- 存储管理的主要方法之连续存储
- Android 4.4.源码 如何屏蔽Home键
- 全排列与回溯法解旅行商问题
- 加入购物车数量的增减
- make ls and chmod command on android device
- Erlang通过WebSocket和浏览器交互
- 菜单与工具栏混合设计
- |NOIOJ|贪心|1797:金银岛
- 如何做好IOS View的布局
- 第十五周阅读程序(3)
- mysql 创建函数 error Code: 1227. Access denied;
- hive优化记录----合并小文件压缩输出
- Android 沉浸式状态栏的实现
- php字符串处理函数大全