dyule / wamp-rs Goto Github PK
View Code? Open in Web Editor NEWImplementation of Web Application Messaging Protocol in Rust
License: MIT License
Implementation of Web Application Messaging Protocol in Rust
License: MIT License
I want to send complex structs over wamp, is there a way to auto (de)serialize them to/from wamp::Value?
http://wamp-proto.org/static/rfc/draft-oberstet-hybi-crossbar-wamp.html#serializations
WAMP defines two bindings for message serialization:
- JSON
- MessagePack
So it should be possible.
Btw, how can I encode floats to send over wamp? (Using autobahn.js on the client)
When I start the router, then the endpoint, the router crashes with:
thread '<unnamed>' panicked at 'no entry found for key', src\libcore\option.rs:7
85
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose bac
ktrace.
stack backtrace:
0: core::option::expect_failed
at C:\projects\rust\src\libcore\option.rs:785
1: core::option::Option<&alloc::arc::Arc<std::sync::mutex::Mutex<wamp::router
::Realm>>>::expect<&alloc::arc::Arc<std::sync::mutex::Mutex<wamp::router::Realm>
>>
at C:\projects\rust\src\libcore\option.rs:293
2: std::collections::hash::map::{{impl}}::index<collections::string::String,c
ollections::string::String,alloc::arc::Arc<std::sync::mutex::Mutex<wamp::router:
:Realm>>,std::collections::hash::map::RandomState>
at C:\projects\rust\src\libstd\collections\hash\map.rs:1341
3: wamp::router::ConnectionHandler::set_realm
at ./src\router\handshake.rs:59
4: wamp::router::ConnectionHandler::handle_hello
at ./src\router\handshake.rs:18
5: wamp::router::ConnectionHandler::handle_message
at ./src\router\messaging.rs:52
6: wamp::router::messaging::{{impl}}::on_message
at ./src\router\messaging.rs:207
7: ws::connection::Connection<wamp::router::ConnectionHandler>::read_frames<w
amp::router::ConnectionHandler>
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\ws-0
.6.0\src\connection.rs:638
8: ws::connection::Connection<wamp::router::ConnectionHandler>::read<wamp::ro
uter::ConnectionHandler>
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\ws-0
.6.0\src\connection.rs:574
9: ws::io::Handler<closure>::handle_event<closure>
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\ws-0
.6.0\src\io.rs:538
10: ws::io::Handler<closure>::event_loop<closure>
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\ws-0
.6.0\src\io.rs:375
11: ws::io::Handler<closure>::run<closure>
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\ws-0
.6.0\src\io.rs:342
12: ws::WebSocket<closure>::run<closure>
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\ws-0
.6.0\src\lib.rs:308
13: ws::WebSocket<closure>::listen<closure,&str>
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\ws-0
.6.0\src\lib.rs:289
14: ws::listen<&str,closure,wamp::router::ConnectionHandler>
at C:\Users\me\.cargo\registry\src\github.com-1ecc6299db9ec823\ws-0
.6.0\src\lib.rs:79
15: wamp::router::{{impl}}::listen::{{closure}}
at ./src\router\mod.rs:97
16: std::panic::{{impl}}::call_once<(),closure>
at C:\projects\rust\src\libstd\panic.rs:296
17: std::panicking::try::do_call<std::panic::AssertUnwindSafe<closure>,()>
at C:\projects\rust\src\libstd\panicking.rs:454
18: panic_unwind::__rust_maybe_catch_panic
at C:\projects\rust\src\libpanic_unwind\lib.rs:98
19: std::panicking::try<(),std::panic::AssertUnwindSafe<closure>>
at C:\projects\rust\src\libstd\panicking.rs:433
20: std::panic::catch_unwind<std::panic::AssertUnwindSafe<closure>,()>
at C:\projects\rust\src\libstd\panic.rs:361
21: std::thread::{{impl}}::spawn::{{closure}}<closure,()>
at C:\projects\rust\src\libstd\thread\mod.rs:360
22: alloc::boxed::{{impl}}::call_box<(),closure>
at C:\projects\rust\src\liballoc\boxed.rs:638
23: std::sys::imp::thread::{{impl}}::new::thread_start
at C:\projects\rust\src\libstd\sys\windows\thread.rs:50
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Any', sr
c\libcore\result.rs:860
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose bac
ktrace.
stack backtrace:
0: core::result::Result<(), alloc::boxed::Box<Any>>::unwrap<(),alloc::boxed::
Box<Any>>
at C:\projects\rust\src\libcore\result.rs:737
1: router::main
at ./examples\router.rs:14
error: process didn't exit successfully: `target\debug\examples\router.exe` (exi
t code: 101)
When I start api_user instead of endpoint, the router also crashes.
These are some possible wamp authentication methods:
https://github.com/crossbario/crossbar-examples/tree/master/authentication
I'm interested in something to replace HTTP Basic auth with username+password, mostly with the cookie method.
ws-rs exposes the Request
through the Handshake
in on_open
, but wamp-rs doesn't expose that.
It would be useful to have a way to use auth cookies with wamp-rs.
Hi!
Thanks for creating this library.
I'd like to ask, are there any plans for support of wss
?
I had a long conversation on #rust-beginners where I tried to register a callback that calls a method on self.
impl A {
pub fn run(self) {
// ...
client.register(uri, Box::new(|args, kwargs| self.authenticate(args, kwargs)));
// ... self is used here
}
}
Complete source code is attached authenticator.zip
We broke the issue down to
fn do_something(callback: Box<FnMut()>) {
callback();
}
struct A<'a> {
name: &'a str,
}
impl<'a> A<'a> {
pub fn run(self) {
do_something(Box::new(|| self.callback()));
}
pub fn callback(&self) {
println!("{}", self.name);
}
}
fn main() {
let a = A { name: "Peter" };
a.run();
}
Two possible solutions were proposed:
fn do_something<'a>(mut callback: Box<FnMut() + 'a>) {
callback();
}
struct A<'a> {
name: &'a str,
}
impl<'a> A<'a> {
pub fn run(self) {
do_something(Box::new(|| self.callback()));
}
pub fn callback(&self) {
println!("{}", self.name);
}
}
fn main() {
let a = A { name: "Peter" };
a.run();
}
and
fn do_something(callback: &mut FnMut())
{
callback();
}
struct A<'a>
{
name: &'a str,
}
impl<'a> A<'a>
{
pub fn run(self)
{
do_something(&mut || self.callback());
}
pub fn callback(&self)
{
println!("{}", self.name);
}
}
fn main()
{
let a = A { name: "Peter" };
a.run();
}
where do_something
is register
or subscribe
. In the IRC it was suggested to alter the signature of register
and subscribe
.
With the current API it is only possible to register functions with no context (e.g. self).
EDIT: shorten example
This crates is somewhat outdated. It uses the deprecated eventual
crate that was replaced by futures
and tokio
. There is a lot of work to be done to shift it to modern state where it can be used with e.g. tokio v0.1
(or tokio v0.2
soon).
Moreover it depends directly on ws
whereas a transport abstraction would be great.
@zrneely started a new project called wamp-proto but its not ready yet.
Instead of maintaining/developing two crates that do the same thing I think it makes sense to combine the efforts.
So @dyule what is your plan within the near future with wamp-rs
?
Does this work with the latest ws-rs and serde?
I have client connected to server and it sometimes reads for seconds sometimes minutes, then it disconnect's with a message:
DEBUG:wamp::client: Result of connection: Ok(())
Reading stops, writes are resulting in error.
DEBUG:wamp::client: Sending message Publish(2, PublishOptions { acknowledge: true }, URI { uri: "test" }, Some([]), None) via wamp.2.msgpack
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { kind: WSError(WS Error <Queue(Disconnected)>) }', /checkout/src/libcore/result.rs:859
Browser haven't had a single connection problem with this server for hours.
I am going to investigate this further tomorrow but maybe someone knows about this issue and what could be causing it.
The client connects over SSL using OpenSSL.
Lines 73 to 78 in e6e8149
When trying to connect to a websocket server that is not running a panic is produced instead of a proper result.
INFO:endpoint: Connecting
INFO:ws: Queuing connection to ws://127.0.0.1:8090/ws
DEBUG:wamp::client: Cloning tranceiver
DEBUG:ws::handshake: Built request from URL:
GET /ws HTTP/1.1
Connection: Upgrade
Host: 127.0.0.1:8090
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: eZXKaj+r5Va/l1APMtWBTw==
Upgrade: websocket
DEBUG:ws::io: Shutting down websocket client.
DEBUG:ws::factory: Factory received WebSocket shutdown request.
DEBUG:wamp::client: Result of connection: Ok(())
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: RecvError', /checkout/src/libcore/result.rs:859
stack backtrace:
0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at /checkout/src/libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at /checkout/src/libstd/sys_common/backtrace.rs:60
at /checkout/src/libstd/panicking.rs:355
3: std::panicking::default_hook
at /checkout/src/libstd/panicking.rs:371
4: std::panicking::rust_panic_with_hook
at /checkout/src/libstd/panicking.rs:549
5: std::panicking::begin_panic
at /checkout/src/libstd/panicking.rs:511
6: std::panicking::begin_panic_fmt
at /checkout/src/libstd/panicking.rs:495
7: rust_begin_unwind
at /checkout/src/libstd/panicking.rs:471
8: core::panicking::panic_fmt
at /checkout/src/libcore/panicking.rs:69
9: core::result::unwrap_failed
at /checkout/src/libcore/macros.rs:29
10: <core::result::Result<T, E>>::unwrap
at /checkout/src/libcore/result.rs:737
11: wamp::client::Connection::connect
at src/client.rs:208
12: endpoint::main
at examples/endpoint.rs:37
13: __rust_maybe_catch_panic
at /checkout/src/libpanic_unwind/lib.rs:98
14: std::rt::lang_start
at /checkout/src/libstd/panicking.rs:433
at /checkout/src/libstd/panic.rs:361
at /checkout/src/libstd/rt.rs:57
15: main
16: __libc_start_main
17: _start
Interestingly the connection result is Ok
although no connection was established. The panic makes it hard to handle a not-running server.
I have the following test server to which I send keystrokes from the Web-UI for my application:
fn main() {
dotenv().unwrap();
env_logger::init().unwrap();
let mut router = Router::new();
router.add_realm("realm1");
info!("Router listening");
let child = router.listen("0.0.0.0:63290");
let connection = Connection::new("ws://127.0.0.1:63290/ws", "realm1");
info!("Connecting");
let mut client = connection.connect().unwrap();
info!("Connected");
info!("Registering Keypress Procedure");
client.register(URI::new("server.keypress"), Box::new(keypress_cb)).unwrap().await().unwrap();
child.join().unwrap();
client.shutdown().unwrap().await().unwrap();
}
fn keypress_cb(args: List, _kwargs: Dict) -> CallResult<(Option<List>, Option<Dict>)> {
args.verify_len(1)?;
let key = args.get_int(0)?.unwrap();
info!("Receiving keypress {}", key);
Ok((Some(vec![Value::Integer(key)]), None))
}
At first it works but after typing a few keys on the web gui, the server stops responding:
[50,2094872376676940,{},[81]] 29
06:54:25.978
[48,8506371253933628,{},"server.keypress",[82],{}] 50
06:54:28.064
[50,8506371253933628,{},[82]] 29
06:54:28.065
[48,3315205349409152,{},"server.keypress",[83],{}] 50
06:54:28.624
[50,3315205349409152,{},[83]] 29
06:54:28.625
[48,4736671216910184,{},"server.keypress",[84],{}] 50
06:54:32.298
[50,4736671216910184,{},[84]] 29
06:54:32.299
[48,8733465103123834,{},"server.keypress",[85],{}] 50
06:54:34.656
[50,8733465103123834,{},[85]] 29
06:54:34.658
[48,6511667357184014,{},"server.keypress",[86],{}] 50
06:54:36.312
[50,6511667357184014,{},[86]] 29
06:54:36.313
[48,5407865983095894,{},"server.keypress",[87],{}] 50
06:54:37.632
[50,5407865983095894,{},[87]] 29
06:54:37.633
[48,3891173192837032,{},"server.keypress",[88],{}] 50
06:54:39.801
[50,3891173192837032,{},[88]] 29
06:54:39.801
[48,3832677989743216,{},"server.keypress",[89],{}] 50
06:54:41.640
[50,3832677989743216,{},[89]] 29
06:54:41.641
[48,7029295605444856,{},"server.keypress",[90],{}] 50
06:54:43.098
[48,3717826704662828,{},"server.keypress",[65],{}] 50
06:54:59.520
[48,1781967526831132,{},"server.keypress",[66],{}] 50
06:55:03.248
[48,5900734383726916,{},"server.keypress",[67],{}] 50
06:55:05.280
[48,1548659696291480,{},"server.keypress",[68],{}] 50
06:55:07.827
[48,831127017980158,{},"server.keypress",[69],{}] 49
06:55:08.113
[48,3160134408701912,{},"server.keypress",[70],{}] 50
06:55:08.696
I typed all the letters from 'a' (65) to 'z' (90), but 'y' (89) was the last time the server responded.
Weirdly, when I reload the page with F5, it works again, for a while, until it stops working again!
The log above is from Chrome dev tools WS tab, after the server stops responding, my client is still correctly sending as far as I can see (I'm using autobahn.js in the client).
More specifically, I'm using wamp-web-components for Polymer:
This is my client code:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/wamp-web-components/wamp-connection.html">
<link rel="import" href="../../bower_components/wamp-web-components/wamp-register.html">
<link rel="import" href="../../bower_components/wamp-web-components/wamp-call.html">
<link rel="import" href="../../bower_components/wamp-web-components/wamp-publish.html">
<link rel="import" href="../../bower_components/wamp-web-components/wamp-subscribe.html">
<dom-module id="my-app">
<template>
<style>
:host {
display: block;
}
</style>
<h2>Hello [[prop1]]</h2>
<wamp-connection
url='ws://127.0.0.1:63290/ws'
realm='realm1'
connected='{{connected}}'
retrying='{{retrying}}'
session='{{session}}'
></wamp-connection>
<template is="dom-if" if="[[connected]]">
<p>Wamp is connected</p>
</template>
<template is="dom-if" if="[[!connected]]">
<p>Wamp is not connected</p>
</template>
<template is="dom-if" if="[[retrying]]">
<p>Autobahn is retrying connection</p>
</template>
<wamp-call id = "call_server_keypress"
method='server.keypress'
args='[]'
session='{{session}}'
last-response='{{res_keypress}}'
on-response='_handleResAdd'
auto
></wamp-call>
<p>[[res_keypress]]</p>
</template>
<script>
Polymer({
is: 'my-app',
properties: {
prop1: {
type: String,
value: 'my-app',
},
},
ready() {
window.onkeydown = function(e) {
var key = e.keyCode;
console.log(key, String.fromCharCode(key));
this.$.call_server_keypress.args = [key];
}.bind(this);
},
_handleResAdd: function(r) {
console.log(r);
}
});
</script>
</dom-module>
What could be the cause of this?
(The reason I'm doing all this is because I want to have a web based GUI for my Rust application.)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.