2018 WebSocket(2)autobahn and Web Application Messaging Protocol

299 篇文章 0 订阅
2018 WebSocket(2)autobahn and Web Application Messaging Protocol

WAMP - Web Application Messaging Protocol provides async Remote Procedure Calls and Publish & Subscribe running over WebSocket
http://wamp-proto.org/

Autobahn Publish and Subscribe
http://blog.csdn.net/lcy930822/article/details/8724994

Autobahn RPC (Remote Procedere Calls)
http://blog.csdn.net/lcy930822/article/details/8725335
registerForRpc(obj, baseUri=‘')
obj is the self, it will provide all @exportRpc methods to clients

registerMethodForRpc(uri, obj, proc)
registerProcedureForRpc(url, proc)

Js Client
Session.call(method, …)
sess.call(“http://example.com#test”, 1, 2, 3).then(function(res){}, function(error){} );

That is some Old Document with Old Version

Install the package we need, start with Python3
> source ~/.virtualenvs/python3env/bin/activate
> sudo pip install autobahn
> sudo pip install twisted
https://autobahn.readthedocs.io/en/latest/wamp/programming.html#running-components

Check the installation
> (python3env) machluo:autobahn hluo$ python
Python 3.6.4 (default, Mar 9 2018, 23:15:03)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from autobahn import __version__
>>> print(__version__)
18.3.1

https://autobahn.readthedocs.io/en/latest/wamp/programming.html

The framework is here
https://github.com/crossbario/autobahn-python
https://autobahn.readthedocs.io/en/latest/index.html

WebSocket allows bidirectional real-time messaging on the Web while WAMP provides applications with high-level communication abstractions. (Remote procedure callings and publish/subscribe)

WAMP is a routed protocol, we need a WAMP router, Corssbar.io
Install autobahn with twisted
> sudo pip install autobahn[twisted]

https://crossbar.io/docs/Getting-Started/
A basic WAMP Application
4 types of Docker Containers, Crossbar.io router, Autobahn|Python, Autobahn|JS, Autobahn|CPP
https://crossbar.io/about/Supported-Languages/

Install crossbar.io on Mac
https://crossbar.io/docs/Installation-on-Mac-OS-X/
> source ~/.virtualenvs/python3env/bin/activate
> sudo pip install crossbar
Check version
> crossbar version
Running on *BSD or MacOSX, but cannot install kqueue Twisted reactor
Running on *BSD or MacOSX, but cannot install kqueue Twisted reactor
Traceback (most recent call last):
File "/Users/hluo/.virtualenvs/python3env/lib/python3.6/site-packages/autobahn/twisted/choosereactor.py", line 68, in install_optimal_reactor
kqreactor.install()
File "/Users/hluo/.virtualenvs/python3env/lib/python3.6/site-packages/twisted/internet/kqreactor.py", line 317, in install
installReactor(p)
File "/Users/hluo/.virtualenvs/python3env/lib/python3.6/site-packages/twisted/internet/main.py", line 32, in installReactor
raise error.ReactorAlreadyInstalledError("reactor already installed")
twisted.internet.error.ReactorAlreadyInstalledError: reactor already installed
__ __ __ __ __ __ __ __
/ `|__)/ \/__`/__`|__) /\ |__) |/ \
\__,| \\__/.__/.__/|__)/~~\| \. |\__/

Crossbar.io : 18.3.1 (Crossbar.io COMMUNITY)
Autobahn : 18.3.1 (with JSON, MessagePack, CBOR, UBJSON)
Twisted : 17.9.0-SelectReactor
LMDB : 0.93/lmdb-0.9.18
Python : 3.6.4/CPython
OS : Darwin-17.4.0-x86_64-i386-64bit
Machine : x86_64
Release key : RWRo1ikD3CYkevlRg/r9/tfXNzulz3+2LB5XZiMkGlGjIhnalP5WoM8M

Create a new Python ENV
> python3 -m venv ~/.virtualenvs/python3new
> source ~/.virtualenvs/python3new/bin/activate

Still have the ReactorAlreadyInstalledError: reactor already installed

> crossbar init
nitializing application template 'default' in directory '/Users/hluo/install'
Using template from '/Users/hluo/.virtualenvs/python3new/lib/python3.6/site-packages/crossbar/templates/default'
Creating directory /Users/hluo/install/.crossbar
Creating directory /Users/hluo/install/web
Creating file /Users/hluo/install/README.md
Creating file /Users/hluo/install/.crossbar/config.json
Creating directory /Users/hluo/install/web/js
Creating file /Users/hluo/install/web/backend.html
Creating file /Users/hluo/install/web/index.html
Creating file /Users/hluo/install/web/frontend.html
Creating file /Users/hluo/install/web/js/CHECKSUM.SHA1
Creating file /Users/hluo/install/web/js/LICENSE
Creating file /Users/hluo/install/web/js/autobahn.min.jgz
Creating file /Users/hluo/install/web/js/autobahn.js
Creating file /Users/hluo/install/web/js/CHECKSUM.MD5
Creating file /Users/hluo/install/web/js/autobahn.min.js
Creating file /Users/hluo/install/web/js/CHECKSUM.SHA256
Application template initialized
To start your node, run 'crossbar start --cbdir /Users/hluo/install/.crossbar'

Start the Server
> crossbar start
2018-03-19T16:36:43-0500 [Controller 93407] New node key pair generated!
2018-03-19T16:36:43-0500 [Controller 93407] File permissions on node private key fixed!
2018-03-19T16:36:43-0500 [Controller 93407] __ __ __ __ __ __ __ __
2018-03-19T16:36:43-0500 [Controller 93407] / `|__)/ \/__`/__`|__) /\ |__) |/ \
2018-03-19T16:36:43-0500 [Controller 93407] \__,| \\__/.__/.__/|__)/~~\| \. |\__/
2018-03-19T16:36:43-0500 [Controller 93407]
2018-03-19T16:36:43-0500 [Controller 93407] Version: Crossbar.io COMMUNITY 18.3.1
2018-03-19T16:36:43-0500 [Controller 93407] Public Key: 2d97f8cca2bccdecb4c8773e631b1e615202febac03104d6183cbe199b9b5c0d
2018-03-19T16:36:43-0500 [Controller 93407]
2018-03-19T16:36:43-0500 [Controller 93407] Node starting with personality "community" [crossbar.controller.node.Node]
2018-03-19T16:36:43-0500 [Controller 93407] Running from node directory "/Users/hluo/install/.crossbar"
2018-03-19T16:36:43-0500 [Controller 93407] Node configuration loaded from "/Users/hluo/install/.crossbar/config.json"
2018-03-19T16:36:43-0500 [Controller 93407] Controller process starting [CPython-SelectReactor] ..
2018-03-19T16:36:43-0500 [Controller 93407] No extra node router roles
2018-03-19T16:36:43-0500 [Controller 93407] RouterServiceSession ready [no on_ready configured]
2018-03-19T16:36:43-0500 [Controller 93407] Registered 20 procedures
2018-03-19T16:36:43-0500 [Controller 93407] Using default node shutdown triggers ['shutdown_on_worker_exit']
2018-03-19T16:36:43-0500 [Controller 93407] Configuring node from local configuration ...
2018-03-19T16:36:43-0500 [Controller 93407] Starting 1 workers ...
2018-03-19T16:36:43-0500 [Controller 93407] Router worker "worker-001" starting ..
2018-03-19T16:36:43-0500 [Router 93409] Started Router worker "worker-001" on node "None" [crossbar.worker.router.RouterWorkerSession / CPython-KQueueReactor]
2018-03-19T16:36:43-0500 [Router 93409] Router worker "worker-001" session 3913861218132874 initializing ..
2018-03-19T16:36:43-0500 [Router 93409] Registered 39 procedures
2018-03-19T16:36:43-0500 [Router 93409] Router worker "worker-001" session ready
2018-03-19T16:36:43-0500 [Controller 93407] Router worker "worker-001" process 93409 started
2018-03-19T16:36:43-0500 [Router 93409] RouterServiceSession ready [configured on_ready fired]
2018-03-19T16:36:43-0500 [Router 93409] Realm 'realm1' started
2018-03-19T16:36:43-0500 [Controller 93407] Router "worker-001": realm 'realm-001' (named 'realm1') started
2018-03-19T16:36:43-0500 [Router 93409] role role-001 on realm realm-001 started
2018-03-19T16:36:43-0500 [Controller 93407] Router "worker-001": role 'role-001' (named 'anonymous') started on realm 'realm-001'
2018-03-19T16:36:43-0500 [Router 93409] UniSocketServerFactory starting on 8080
2018-03-19T16:36:43-0500 [Controller 93407] Router "worker-001": transport 'transport-001' started
2018-03-19T16:36:43-0500 [Controller 93407] Local node configuration applied successfully!

Clients
Components is the parts for caller and callee in RPC or Publisher or Subscriber

RPC Mode
Caller, Callee, Dealer
Caller, call remote with url and parameters.
Callee execute the method with parameters

Callee will register in Dealer(crossbar.io), Caller will go Dealer, Dealer will route to Callee, return the response back to Caller
Caller and Callee will execute the codes, Dealer is doing the routing.

PubSub Mode
Publisher, Subscriber, Broker
Publisher provide URL and payload, Subscribers listen to information, Broker is the place for pub/sub

Install crossbar.io on Docker
Pull the docker image
> docker pull crossbario/crossbar

Start the crossbar Application
> docker run --rm -it -p 8080:8080 --name corssbar crossbario/crossbar
2018-03-19T21:50:42+0000 [Controller 1] New node key pair generated!
2018-03-19T21:50:42+0000 [Controller 1] File permissions on node private key fixed!
2018-03-19T21:50:42+0000 [Controller 1] __ __ __ __ __ __ __ __
2018-03-19T21:50:42+0000 [Controller 1] / `|__)/ \/__`/__`|__) /\ |__) |/ \
2018-03-19T21:50:42+0000 [Controller 1] \__,| \\__/.__/.__/|__)/~~\| \. |\__/
2018-03-19T21:50:42+0000 [Controller 1]
2018-03-19T21:50:42+0000 [Controller 1] Version: Crossbar.io COMMUNITY 18.3.1
2018-03-19T21:50:42+0000 [Controller 1] Public Key: cbd9a7f95280ba8e0f38adc329ea3efbb32fc80751dccb4e14143691949b4871
2018-03-19T21:50:42+0000 [Controller 1]

We see the status from browser
http://localhost:8080/

More example
https://github.com/crossbario/crossbar-examples

It will start the crossbar on {PWD} mapping to /node directory
> docker run -v ${PWD}:/node -p 8080:8080 --name corssbar --rm -it crossbario/crossbar
2018-03-19T21:57:00+0000 [Controller 1] __ __ __ __ __ __ __ __
2018-03-19T21:57:00+0000 [Controller 1] / `|__)/ \/__`/__`|__) /\ |__) |/ \
2018-03-19T21:57:00+0000 [Controller 1] \__,| \\__/.__/.__/|__)/~~\| \. |\__/
2018-03-19T21:57:00+0000 [Controller 1]
2018-03-19T21:57:00+0000 [Controller 1] Version: Crossbar.io COMMUNITY 18.3.1
2018-03-19T21:57:00+0000 [Controller 1] Public Key: 2d97f8cca2bccdecb4c8773e631b1e615202febac03104d6183cbe199b9b5c0d
2018-03-19T21:57:00+0000 [Controller 1]
2018-03-19T21:57:00+0000 [Controller 1] Node starting with personality "community" [crossbar.controller.node.Node]
2018-03-19T21:57:00+0000 [Controller 1] Running from node directory "/node/.crossbar"
2018-03-19T21:57:00+0000 [Controller 1] Node configuration loaded from "/node/.crossbar/config.json"
2018-03-19T21:57:00+0000 [Controller 1] Controller process starting [CPython-EPollReactor] ..
2018-03-19T21:57:00+0000 [Controller 1] No extra node router roles
2018-03-19T21:57:00+0000 [Controller 1] RouterServiceSession ready [no on_ready configured]
2018-03-19T21:57:00+0000 [Controller 1] Registered 20 procedures
2018-03-19T21:57:00+0000 [Controller 1] Using default node shutdown triggers ['shutdown_on_worker_exit']
2018-03-19T21:57:00+0000 [Controller 1] Configuring node from local configuration ...
2018-03-19T21:57:00+0000 [Controller 1] Starting 1 workers ...
2018-03-19T21:57:00+0000 [Controller 1] Router worker "worker-001" starting ..
2018-03-19T21:57:00+0000 [Router 17] Started Router worker "worker-001" on node "None" [crossbar.worker.router.RouterWorkerSession / CPython-EPollReactor]
2018-03-19T21:57:00+0000 [Router 17] Router worker "worker-001" session 7142620542222432 initializing ..
2018-03-19T21:57:00+0000 [Router 17] Registered 39 procedures
2018-03-19T21:57:00+0000 [Router 17] Router worker "worker-001" session ready
2018-03-19T21:57:00+0000 [Controller 1] Router worker "worker-001" process 17 started
2018-03-19T21:57:00+0000 [Router 17] RouterServiceSession ready [configured on_ready fired]
2018-03-19T21:57:00+0000 [Router 17] Realm 'realm1' started
2018-03-19T21:57:00+0000 [Controller 1] Router "worker-001": realm 'realm-001' (named 'realm1') started
2018-03-19T21:57:00+0000 [Router 17] role role-001 on realm realm-001 started
2018-03-19T21:57:00+0000 [Controller 1] Router "worker-001": role 'role-001' (named 'anonymous') started on realm 'realm-001'
2018-03-19T21:57:00+0000 [Router 17] UniSocketServerFactory starting on 8080
2018-03-19T21:57:00+0000 [Controller 1] Router "worker-001": transport 'transport-001' started
2018-03-19T21:57:00+0000 [Controller 1] Local node configuration applied successfully!

We can visit the status here
http://localhost:8080/

Read the sample codes in web and .crossbar configuration to understand that.

We can open the Browser and see the applications running
http://localhost:8080/frontend.html
<!DOCTYPE html>
<html>
<body>
<h1>Hello WAMP/Browser - Frontend</h1>
<p>Open JavaScript console to watch output.</p>
<script>AUTOBAHN_DEBUG = false;</script>
<script src="js/autobahn.min.js"></script>

<script>
console.log("Runnning on AutobahnJS ", autobahn.version);

// the URL of the WAMP Router (Crossbar.io)
//
var wsuri;
if (document.location.origin == "file://") {
wsuri = "ws://127.0.0.1:8080/ws";

} else {
wsuri = (document.location.protocol === "http:" ? "ws:" : "wss:") + "//" +
document.location.host + "/ws";
}


// the WAMP connection to the Router
//
var connection = new autobahn.Connection({
url: wsuri,
realm: "realm1"
});


// timers
//
var t1, t2;


// fired when connection is established and session attached
//
connection.onopen = function (session, details) {

console.log("Connected: ", details);

// SUBSCRIBE to a topic and receive events
//
function on_counter (args) {
var counter = args[0];
console.log("on_counter() event received with counter " + counter);
}
session.subscribe('com.example.oncounter', on_counter).then(
function (sub) {
console.log('subscribed to topic');
},
function (err) {
console.log('failed to subscribe to topic', err);
}
);


// PUBLISH an event every 2 seconds .. forever
//
t1 = setInterval(function () {

session.publish('com.example.onhello', ['Hello from JavaScript (browser)']);
console.log("published to topic 'com.example.onhello'");
}, 2000);


// REGISTER a procedure for remote calling
//
function mul2 (args) {
var x = args[0];
var y = args[1];
console.log("mul2() called with " + x + " and " + y);
return x * y;
}
session.register('com.example.mul2', mul2).then(
function (reg) {
console.log('procedure registered');
},
function (err) {
console.log('failed to register procedure', err);
}
);


// CALL a remote procedure every 2 seconds .. forever
//
var x = 0;

t2 = setInterval(function () {

session.call('com.example.add2', [x, 18]).then(
function (res) {
console.log("add2() result:", res);
},
function (err) {
console.log("add2() error:", err);
}
);

x += 3;
}, 2000);
};


// fired when connection was lost (or could not be established)
//
connection.onclose = function (reason, details) {
console.log("Connection lost: " + reason);
if (t1) {
clearInterval(t1);
t1 = null;
}
if (t2) {
clearInterval(t2);
t2 = null;
}
}


// now actually open the connection
//
connection.open();

</script>
</body>
</html>


http://localhost:8080/backend.html
<!DOCTYPE html>
<html>
<body>
<h1>Hello WAMP/Browser - backend</h1>
<p>Open JavaScript console to watch output.</p>
<script>AUTOBAHN_DEBUG = false;</script>
<script src="js/autobahn.min.js"></script>

<script>
console.log("Runnning on AutobahnJS ", autobahn.version);

// the URL of the WAMP Router (Crossbar.io)
//
var wsuri;
if (document.location.origin == "file://") {
wsuri = "ws://127.0.0.1:8080/ws";

} else {
wsuri = (document.location.protocol === "http:" ? "ws:" : "wss:") + "//" +
document.location.host + "/ws";
}


// the WAMP connection to the Router
//
var connection = new autobahn.Connection({
url: wsuri,
realm: "realm1"
});


// timers
//
var t1;


// fired when connection is established and session attached
//
connection.onopen = function (session, details) {

console.log("Connected: ", details);

// SUBSCRIBE to a topic and receive events
//
function onhello (args) {
var msg = args[0];
console.log("event for 'onhello' received: " + msg);
}
session.subscribe('com.example.onhello', onhello).then(
function (sub) {
console.log("subscribed to topic 'onhello'");
},
function (err) {
console.log("failed to subscribed: " + err);
}
);


// REGISTER a procedure for remote calling
//
function add2 (args) {
var x = args[0];
var y = args[1];
console.log("add2() called with " + x + " and " + y);
return x + y;
}
session.register('com.example.add2', add2).then(
function (reg) {
console.log("procedure add2() registered");
},
function (err) {
console.log("failed to register procedure: " + err);
}
);


// PUBLISH and CALL every 2 seconds .. forever
//
var counter = 0;
t1 = setInterval(function () {

// PUBLISH an event
//
session.publish('com.example.oncounter', [counter]);
console.log("published to 'oncounter' with counter " + counter);

// CALL a remote procedure
//
session.call('com.example.mul2', [counter, 3]).then(
function (res) {
console.log("mul2() called with result: " + res);
},
function (err) {
if (err.error !== 'wamp.error.no_such_procedure') {
console.log('call of mul2() failed: ' + err);
}
}
);

counter += 1;
}, 2000);
};


// fired when connection was lost (or could not be established)
//
connection.onclose = function (reason, details) {
console.log("Connection lost: " + reason);
if (t1) {
clearInterval(t1);
t1 = null;
}
}


// now actually open the connection
//
connection.open();

</script>
</body>
</html>


References:
https://github.com/crossbario/autobahn-js
https://crossbar.io/autobahn/
http://blog.csdn.net/lcy930822/article/details/8724994
http://blog.csdn.net/lcy930822/article/details/8725335
http://blog.51cto.com/iceyao/1865218
https://www.zybuluo.com/orangleliu/note/472867
http://blog.csdn.net/qq_34134278/article/details/78252766
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值