我创建了一个简单的appmod,它在接收到消息时会发回相同的消息。但我在命令提示符处收到一条错误消息,WebSocket连接已关闭。
如果我发送一条包含3个字符的消息,我会收到以下错误消息:
=ERROR REPORT==== 8-Feb-2012::05:09:14 ===
Error in process <0.59.0> with exit value: {undef,[{mywebsocket,handle_message,[
{text,<<3 bytes>>}],[]},{lists,map,2,[{file,"lists.erl"},{line,1173}]},{yaws_web
sockets,loop,4,[{file,"yaws_websockets.erl"},{line,151}]}]}
我做错了什么?句柄使用text
,如果我使用binary
,它也不起作用。
这是我的HTML+JavaScript客户端:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script>
window.onload = function() {
document.getElementById('sendbutton').addEventListener('click', sendMessage, false);
document.getElementById('connectbutton').addEventListener('click', connect, false);
document.getElementById('disconnectbutton').addEventListener('click', disconnect, false);
}
function writeStatus(message) {
var html = document.createElement("div");
html.setAttribute("class", "message");
html.innerHTML = message;
document.getElementById("status").appendChild(html);
}
function connect() {
ws = new WebSocket("ws://localhost:8090/ws.yaws");
ws.onopen = function(evt) {
writeStatus("connected");
}
ws.onclose = function(evt) {
writeStatus("disconnected");
}
ws.onmessage = function(evt) {
writeStatus("response: " + evt.data);
}
ws.onerror = function(evt) {
writeStatus("error: " + evt.data);
}
}
function disconnect() {
ws.close();
}
function sendMessage() {
var msg = document.getElementById('messagefield').value
ws.send(msg);
}
</script>
</head>
<body>
<h1>Chat</h1>
<button id="connectbutton">Connect</button>
<button id="disconnectbutton">Disconnect</button><br/>
<input type="text" id="messagefield"/><button id="sendbutton">Send</button>
<div id="status"></div>
</body>
</html>
在连接上从客户端调用的ws.yaws
如下所示:
<erl>
out(A) -> {websocket, mywebsocket, []}.
</erl>
我的回调appmodmywebsocket.erl
看起来像这样:
-module(mywebsocket).
-export([handle_message/1]).
handle_message({text, Message}) ->
{reply, {text, Message}}.
在yaws.conf
中,我将服务器配置为:
<server localhost>
port = 8090
listen = 0.0.0.0
docroot = "C:UsersJonas/yawswww"
appmods = <ws, mywebsocket>
</server>
我使用Yaws 1.92和Chrome 16。
可能是您的appmod不在PATH中,或者其模块没有加载到yaws web服务器VM实例或shell中。一旦您的web服务器启动,请尝试在yaws shell中调用此方法:
1> mywebsocket:handle_message({text,"某些数据"})。如果它在偏航外壳中运行得很好,那么这意味着它在PATH中。错误为
undef
,这意味着函数调用失败,因为函数所在的模块未加载。
现在,在yaws.conf
文件中,对其进行编辑,以包含您的appmod的编译文件所在的ebin文件夹。实际上,一定要把所有的路径添加到你的appmod所依赖的可执行代码中。它应该看起来像这样:
# This the path to a directory where additional
# beam code can be placed. The daemon will add this
# directory to its search path
ebin_dir = "F:/programming work/erlcharts-1.0/ebin"
ebin_dir = "C:/SomeFolder/another_library-1.0/ebin"
ebin_dir = "D:/Any/Folder/myappmods"
# This is a directory where application specific .hrl
# files can be placed. application specifig .yaws code can
# then include these .hrl files
include_dir = "C:Program Files (x86)Yaws-1.90/examples/include"
include_dir = "D:/Any/Folder/myappmods/include"
现在,在yaws conf文件中输入所有代码的路径。不要担心前斜线或后斜线,偏航总是能绕过路径。对于UNIX/LINUX,它保持不变,例如ebin_dir = "/usr/local/lib/erlang/lib/myapp-1.0/ebin"
。
但是,请注意,在yaws web服务器完全初始化之前,您的模块将不会加载