Pull to refresh

Удаленный вызов процедур в Node.js с использованием Now.js

Reading time4 min
Views5.5K

Введение


Для Node.js есть отличная библиотека Socket.io для кроссбраузерного использования вебсокетов.
Но для двухстороннего взаимодействия сервера и клиента приходится использовать модель сообщений.
С помощью библиотеки Now.js есть возможность прозрачного вызова функций клиента со стороны сервера и наоборот.

Как это выглядит


Now.js — Node.js модуль поверх Socket.io, предоставляющий возможности вызова функций клиента со стороны сервера и наоборот. Также со стороны клиента и сервера можно не только вызывать функции, но и использовать общие переменные.
Для начала обсудим минимум кода, который нужен для того, чтобы у нас заработали удаленные вызовы.

Серверная часть

rpc = require "now"
rpc_channel
= rpc.initialize httpServer
rpc_channel
.now.myVariable = "some value"
rpc_channel
.now.distribute = (message) ->
   rpc_channel
.now.receive @now.name, message
Этот исходный код отформатирован с помощью FractalizeR's HabraSyntax Source Code Highlighter.

Что здесь происходит:
  1. Загружаем модуль Now.js
  2. Создаем канал для вызова методов, передавая методу initialize экземпляр запущенного Node.js сервера(http.Server)
  3. В полученном канале есть объект now через который и идет синхронизация между клиентом и сервером. Для примера в объект помещена переменная myVariable, которая будет видна клиентам
  4. Помещаем в объект now функцию distribute, теперь ее могут вызывать клиенты
  5. В функции distribute вызываем метод receive у клиента

Клиентская часть

console.log(now.myVariable);
now
.receive = function(message){
$
("#messages").append("<br>"+message);
}
$
("#send-button").click(function(){
now
.distribute($("#text-input").val());
});
Этот исходный код отформатирован с помощью FractalizeR's HabraSyntax Source Code Highlighter.

Что здесь происходит:
  1. Некоторым образом используем переменную определенную на сервере
  2. Определяем функцию, которую сможет вызвать сервер(объект now похож на серверный)
  3. В некотором месте(в данном случае в обработчике события нажатия на кнопку) мы вызываем серверную функцию

Пишем чат с использованием Now.js и Kiss.js


Контроллер

kiss = require "kiss.js"
rpc
= kiss.controllers.rpc
class MyController
    @on_app_started
= (app) ->
        app
.rpc_channel.now.distributeMessage = (message) ->
            gr
= rpc.getGroup @now.room
            gr
.removeUser @user.clientId
            gr
= rpc.getGroup @now.new_room
            gr
.addUser @user.clientId
            @now
.room = @now.new_room
            gr
.now.receiveMessage @now.name, message
    @
index = (req, res) ->
        context
= { template_name: "chat.html" }
        v
= new kiss.views.TextViewer()
        v
.render req, res, context
exports
.MyController = MyController
Этот исходный код отформатирован с помощью FractalizeR's HabraSyntax Source Code Highlighter.

В index мы просто генерируем страницу чата, а вот все самое интересное происходит в on_app_started.
Этот метод выполняется при старте приложения. Здесь мы определяем функцию distributeMessage, которую будет вызывать клиент. При вызове мы перемещаем пользователя в комнату new_room и рассылаем всем сообщение.

Клиент

$(document).ready(function()
{
    now
.name = "user";
    now
.room = "room 1";
    function send()
    {
        now
.name = $('<div/>').text($("#username").val()).html();
        now
.new_room = $('<div/>').text($("#room").val()).html();
        var html = $('<div/>').text($("#text-input").val()).html();        
        now
.distributeMessage(html);
        $
("#text-input").val("");
    }
    $
("#send-button").click(send);
    $
("#text-input").keypress(function(e)
    {
        if(e.keyCode == 13) send();
    });
    now
.receiveMessage = function(name, message)
    {
        $
("<li><h3>" + name + "</h3><p><strong>" + message + "</strong></p></li>").prependTo("#messages");
        $
('#messages').listview('refresh');
    }
});
Этот исходный код отформатирован с помощью FractalizeR's HabraSyntax Source Code Highlighter.

При загрузке документа указываем имя пользователя и комнату по умолчанию и создаем функцию, которая будет вызвана при щелчке по кнопке. В этой функции мы получаем имя, комнату и сообщение и отсылаем все это на сервер.
Также мы определяем функцию, которую вызовет сервер для уведомления о получении сообщения.
Результат можно посмотреть здесь.
Люди в комнате с одним названием будут видеть сообщения друг друга, сообщения нигде не сохраняются, так как это просто тестовый пример.

Как видим с помощью Now.js мы имеем возможность синхронизации переменных и прозрачного вызова функций и со стороны сервера, и со стороны клиента, что может быть удобно при построении приложений реального времени.

Ссылки


Демо
Исходный код чата
Now.js
Socket.io
Kiss.js
Tags:
Hubs:
+14
Comments10

Articles