Как обрабатывать сообщения WebSocket в appmod с помощью Yaws?

Я создал простой мод приложения, который отправляет обратно то же сообщение, что и получает. Но я получаю сообщение об ошибке в командной строке, и соединение 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>

И мой обратный вызов appmod mywebsocket.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:\Users\Jonas/yawswww"
    appmods = <ws, mywebsocket>
</server>

Я использую Yaws 1.92 и Chrome 16.


person Jonas    schedule 08.02.2012    source источник


Ответы (1)


Probably, your appmod is not in PATH, or its module is not loaded in the yaws web server VM instance or shell. Try to call this method in the yaws shell once your web server starts:

1> mywebsocket:handle_message({text,"Some Data"}).
If it runs very well in the yaws shell, then it means that its in PATH. The error is undef meaning that the function call is failing because the module in which the function is contained, is not loaded.


Теперь в файле yaws.conf отредактируйте его, чтобы включить папку ebin, в которой находится скомпилированный файл вашего мода приложения. На самом деле обязательно добавьте все ПУТИ к исполняемому коду, от которого зависит ваш мод приложения. это должно выглядеть так:

# 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"

Теперь введите PATH для всего вашего кода в файле конфигурации yaws. Не беспокойтесь о косой черте или обратной косой черте, рыскание всегда проходит через пути. Для UNIX/LINUX это остается прежним, например. ebin_dir = "/usr/local/lib/erlang/lib/myapp-1.0/ebin".

Однако обратите внимание, что ваши модули не будут загружены до тех пор, пока веб-сервер yaws не будет полностью инициализирован.

person Muzaaya Joshua    schedule 08.02.2012
comment
Спасибо, это сработало. Я также добавил содержимое из вашего другого поста в этот ответ. Вы должны редактировать свои ответы, а не публиковать новые. - person Jonas; 08.02.2012