Giter Site home page Giter Site logo

wamp-server's Introduction

WAMP Router Server

NPM version Build Status Test coverage Greenkeeper badge

Implemented by following the WAMP standards.

Compatible with Autobahn JS

Currently only the Basic Profile is implemented.

  • hello
  • welcome
  • abort
  • goodbye
  • error
  • publish
  • published
  • subscribe
  • subscribed
  • unsubscribe
  • unsubscribed
  • event
  • call
  • result
  • register
  • registered
  • unregister
  • unregistered
  • invocation
  • yield

Why

The other two node implementations have memory leaks.

Note

The current source is written in Typescript and the release is the compiled javascript version. Once ES6 modules land in node, the only significant difference between the src/ and the release/ will be the types. At some point, the implementation may be moved to node completely.

Installation

$ npm install wamp-server

Usage

'use strict';
const WAMP_SERVER = require('wamp-server');
const SERVER = new WAMP_SERVER({
  port: 8000,
  realms: ['com.example.inge'], // array or string
});
// to close the server - SERVER.close();

Debugging

For debugging you can use the DEBUG variable - DEBUG=wamp:*

Contributing

Any contribution will be highly appreciated

Development

$ npm install
$ typings install
$ npm run dev

Tests

To run the test suite, first install the dependencies, then run npm test:

$ npm install
$ npm test

License

MIT

wamp-server's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

wamp-server's Issues

Upgrade ws package

The latest ws package is now 4.0, but this project is still using ws 2.0.
I did some basic benchmark with sending 20000 rpc to add two numbers in parallel. The result of using ws 2.0 is 1300ms (wamp.rt uses ws 0.8 with 2000ms), while using ws 4.0 (without check protocol) is 750ms. This is a huge impact and it is worth for a dependency upgrade.

But I notice that ws api has been changed a bit. There an error of obtain ip address during startup. Here is the description of the api change websockets/ws#1099

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml
  • The new Node.js version is in-range for the engines in 1 of your package.json files, so that was left alone

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Stuck at joining realm when working with autobahn-cpp

I have an issue when using this with autobahn-cpp. I run this server with node wamp.js with content same as the example:

'use strict';
let server = require('wamp-server');
const SERVER = new server({
    port: 8000,
    realms: ['com.example.inge'], // array or string
});

and a simple autobahn-cpp application with code similar to the example here:

#include <boost/asio.hpp>

#include <autobahn/autobahn.hpp>
#include <autobahn/wamp_websocketpp_websocket_transport.hpp>
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <boost/version.hpp>
#include <iostream>
#include <memory>
#include <string>
#include <tuple>
using boost::asio::io_service;
void add2(autobahn::wamp_invocation invocation) {
  auto a = invocation->argument<uint64_t>(0);
  auto b = invocation->argument<uint64_t>(1);

  std::cerr << "Procedure com.examples.calculator.add2 invoked: " << a << ", "
            << b << std::endl;

  invocation->result(std::make_tuple(a + b));
}

int main(argc, char** argv)
{
try {
    io_service io;
    bool debug = true;
    client ws_client;
    ws_client.init_asio(&io);
    //    auto m_rawsocket_endpoint =
    //        tcp::endpoint(address::from_string("127.0.0.1"), 8000);
    std::string realm = "com.example.inge";
    auto transport =
        std::make_shared<autobahn::wamp_websocketpp_websocket_transport<
            websocketpp::config::asio_client> >(
            ws_client, "ws://127.0.0.1:8000/ws", debug);
    auto session = std::make_shared<autobahn::wamp_session>(io, debug);

    // Create a thread to run the telemetry loop
    transport->attach(
        std::static_pointer_cast<autobahn::wamp_transport_handler>(session));

    // Make sure the continuation futures we use do not run out of scope
    // prematurely.
    // Since we are only using one thread here this can cause the io service to
    // block
    // as a future generated by a continuation will block waiting for its
    // promise to be
    // fulfilled when it goes out of scope. This would prevent the session from
    // receiving
    // responses from the router.
    boost::future<void> connect_future;
    boost::future<void> start_future;
    boost::future<void> join_future;
    boost::future<void> provide_future;
    boost::future<void> call_future;

    connect_future = transport->connect().then([&](
        boost::future<void> connected) {
      try {
        connected.get();
      } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        io.stop();
        return;
      }

      std::cerr << "transport connected" << std::endl;

      start_future = session->start().then([&](boost::future<void> started) {
        try {
          started.get();
        } catch (const std::exception& e) {
          std::cerr << e.what() << std::endl;
          io.stop();
          return;
        }

        std::cerr << "session started" << std::endl;

        join_future = session->join(realm).then([&](
            boost::future<uint64_t> joined) {
          try {
            std::cerr << "joined realm: " << joined.get() << std::endl;
          } catch (const std::exception& e) {
            std::cerr << e.what() << std::endl;
            io.stop();
            return;
          }

          autobahn::wamp_call_options call_options;
          call_options.set_timeout(std::chrono::seconds(10));

          std::tuple<uint64_t, uint64_t> arguments(2, 5);
          call_future =
              session->call("com.example.mul2", arguments, call_options)
                  .then([&](boost::future<autobahn::wamp_call_result> result) {
                    try {
                      uint64_t sum = result.get().argument<uint64_t>(0);
                      std::cerr << "call result: " << sum << std::endl;
                    } catch (const std::exception& e) {
                      std::cerr << "call failed: " << e.what() << std::endl;
                      io.stop();
                      return;
                    }

                    provide_future =
                        session->provide("com.example.add2", &add2)
                            .then([&](boost::future<autobahn::wamp_registration>
                                          registration) {
                              try {
                                std::cerr << "registered procedure:"
                                          << registration.get().id()
                                          << std::endl;
                              } catch (const std::exception& e) {
                                std::cerr << e.what() << std::endl;
                                io.stop();
                                return;
                              }

                            });
                  });
        });

      });
    });

    std::cerr << "starting io service" << std::endl;

    io.run();

    std::cerr << "stopped io service" << std::endl;

  } catch (const std::exception& e) {
    std::cerr << "exception: " << e.what() << std::endl;
    return -1;
  }
}

when I run this, it will get stuck after showing

starting io service
transport connected
session started
TX message (135 octets) ...
TX message: hello ["com.example.inge", {"authid":"", "authmethods":[], "roles":{"subscriber":{}, "callee":{"features":{"call_timeout":true}}, "publisher":{}, "caller":{"features":{"call_timeout":true}}}}]

so the joining step seems a failure. But if I run the above cpp program together with a configured crossbar router, the joining step can be successful. And I get correct results with wamp-server as router and autobahn js as client. I' m wondering what would be the cause of the problem when using wamp-server and autobahn-cpp together?

Thanks!

Handle published message strange

I use autobahn-python to subscribe a topic and then use autobahn-js to publish message to this topic. But somehow, autobahn-python doesn't understand the protocol. In concrete, in autobahn-python received message is

[36, 8483690563665722, 8483690563665722, 'testpy.echo', [], {}]

As you can see, the 4th parameter is the topic uri. But autobahn-python expects it to be some details object. like this

[36, 8483690563665722, 8483690563665722, {topic: 'testpy.echo'}, [], {}]

As you know, crossbar router has many extra features. I'm not sure whether autobahn-python only supports some very advanced message format. So I asked them link , whether my message is valid or not. They claim that their implementation follows the WAMP RPC spec. They told me their implementation is correct.

So I made some experiments on wamp-server side. In the notify method (see handler.js)

if (SESSION.getID() !== event.session.getID()) {
        DEBUG('notifying sessionID: %s', SESSION.getID());
        SESSION.send([
          outgoingChannel.EVENT,
          SESSION.getSubscriptionID(event.topic),
          event.subscription.subscriptionID,
          //event.message.incoming[3],
          {topic: event.message.incoming[3]}, // this is my work around
          event.message.incoming[4],
          event.message.incoming[5],
        ]);
      }

And then autobahn-python can receive published message successfully. Do you think this is an error of wamp-server?

tests failure

Hi! suddenly tests starts falling.

1) wamp Should create two clients, make RPC and pub / sub:
     Uncaught TypeError: Cannot read property 'mask' of undefined
      at Sender.frameAndSend (node_modules/ws/lib/Sender.js:206:17)
      at node_modules/ws/lib/Sender.js:126:12
      at node_modules/ws/lib/PerMessageDeflate.js:313:5
      at afterWrite (_stream_writable.js:386:3)
      at onwrite (_stream_writable.js:377:7)
      at afterTransform (_stream_transform.js:79:3)
      at TransformState.afterTransform (_stream_transform.js:54:12)
      at Zlib.callback (zlib.js:625:5)

Cannot handshake with autobahn-python client

First of all, thank you creating such a great WAMP router for js folks. It's super easy to integrate with autobahn-js, but unfortunately, I failed to integrate it with autobahn-python.

I did some investigation and found the root cause. The first problem is that autobahn-python uses MsgpackSerializer by default, which is not supported by wamp-server. So that wamp-server is not able to understand the binary data sent from Python. I current solve this problem by specify JsonSerializer in Python code.

After the first problem is solved, my python client still cannot handshake with wamp-server. I notice there is a simple typo in code. brokder should be broker. The typo is even in test case. I guess this is the reason why all test cases are passed successfully.

I have created a PR, hope you can review it and merge it.

Allow using an existing WebSocket

Is there a way to use this library without creating a server? I'm using express-ws and would like to use the WebSocket object provided directly with this library.

Error: Cannot find module 'wamp-server/src/server'

I exactly did what the "example" folder said.

I just replaced the "../" with the modules name.
Raw:
import Server from 'wamp-server/src/server';

Replaced:
import Server from '../src/server';

and the rest:

export class WampRouter {
    private wss;

    constructor(port: number, realm: string) {
        this.wss = new Server({
            port: port,
            realms: [realm]
        });
   }
}

Error: read ECONNRESET

This is not necessarily an error with wamp-server, but it is effecting a fully update to date environment.

Using wamp-server 0.0.7, which pulled in ws 4.0.0.

We are running wamp-server as the router using PM2, and getting the following error:

4|wrte | Error: read ECONNRESET
4|wrte |     at _errnoException (util.js:1022:11)
4|wrte |     at TCP.onread (net.js:615:25)
PM2        | App [wrte] with id [4] and pid [28463], exited with code [1] via signal [SIGINT]
3|wamp | lost { reason: null,
3|wamp |   message: null,
3|wamp |   retry_delay: 1.4510242141984613,
3|wamp |   retry_count: 1,
3|wamp |   will_retry: true }

The wrte app above, is just starting a wamp-server instance - and that's it:

server = require('wamp-server'),
    Server = new server({
      port: port,
      realms: [realm], // array or string 
    });

This is causing PM2 to see the error and restart the service.

It looks like this can be tied to this issue on the WebSockets library: websockets/ws#1256

Looks like handling the error event from the socketinterface in SessionManager.createSession should take care of it: websockets/ws#1256 (comment).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.