websockets-rs / rust-websocket Goto Github PK
View Code? Open in Web Editor NEWA WebSocket (RFC6455) library written in Rust
Home Page: http://websockets-rs.github.io/rust-websocket/
License: MIT License
A WebSocket (RFC6455) library written in Rust
Home Page: http://websockets-rs.github.io/rust-websocket/
License: MIT License
This seemed like a good place for this. I wanted to flesh out a few things I was thinking about.
There are many websocket libraries out there today but this one is the coolest, and it can be cooler!
There are many missing features and pain points of the library that I wanted to discuss and I thought I would list them here. We should also include some features from other libraries and become the best ws library out there!
Features:
hyper
requests and turn them into websocketshyper
and others can be kept under a feature.Cookies
is probably useful, etc.net2
cratemio
support
protocols
Pain Points:
hyper
is overkill. still not 100% sure.
http-muncher
or httparse
+ some header library might be OKstdlib
, see websocket-streamFuture:
This mostly spawned out of me trying to fix #53, and I thought we should discuss some API before I sink more time into it. If we're all clear on what we want it to look like we can easily split up work and people can more easily contribute.
So @cyderize to start off do you think this list is complete? I have some API ideas I'll post soon.
I have been tracking down a series of intermittent failures inside servos test suite to do with Websockets. The original issue is available here servo/servo#9803 but it's full of crazy thoughts and lots of distractions and is probably best to ignore.
I believe I have tracked down the issue to a problem in the way rust-websocket reads the handshake response and then transfers over to reading the BufReader itself. What happens is occasionally when hyper reads the handshake response into the buffer it also pulls with it the next message(s) aswell. So when parse_response returns the BufReader is setup that it's position points to the next message that is in it's internal buffer and the stream has been completely consumed.
https://github.com/cyderize/rust-websocket/blob/master/src/client/response.rs#L45
let response = try!(parse_response(reader));
This becomes a problem when begin() in response.rs is called to create a sender and receiver, this function throws away the previous BufReader by sending the inner stream to Receiver that creates a new BufReader so everything inside the old buffer that was ready to be parsed is lost.
https://github.com/cyderize/rust-websocket/blob/master/src/client/response.rs#L133
This issue is made more frequent by servos test suite because a lot of the tests send the first websocket message instantly after the handshake response, so the issue pops up there a lot more often.
I'll create a pull request with what I think is an easy solution to the problem but I'm not sure if it's the best thing to do. It just moves the BufReader over to reciever instead of the internal stream.
Or the documentation doesn't say.
Hello, I'd love to use rust-websocket for a project I'm working on. I'd like to make a server (using iron or hyper) that supports both HTTP connections and WebSocket connections. I imagine this is a common use case. Is this possible with the current API? If so, perhaps a simple example in the docs would be very helpful.
The bulk of this library will be rewritten using much nicer associated types.
This will be happening in the dev branch, and will be merged into master when complete, removing the annoying old_impl_check warnings.
This is a requirement for Servo, to allow for things like Cookie headers that the browser environment must send.
So I can't seem to get a secure socket server running correctly, each successful connection returns a "Bad file descriptor" error upon read_request
. Strangely, the sample runs perfectly fine if I use Server::bind
instead of Server::bind_secure
. I've tested this on Ubuntu 15.04 64bit and OSX 10.10.5, the same issue persists.
I was also able to get an Iron server working with the same SSL certificates, so I'm fairly sure that hyper is not the issue here.
Example code: (You need a valid certificate saved as certs/cert.pem
and key as certs/privkey.pem
)
extern crate websocket;
extern crate openssl;
use std::thread;
use std::path::Path;
use websocket::{Client, Message, Server};
use websocket::client::request::Url;
use openssl::ssl::{SslContext, SslMethod};
use openssl::x509::X509FileType;
fn main() {
// Set up SSL
let mut context = SslContext::new(SslMethod::Tlsv1).unwrap();
let _ = context.set_certificate_file(Path::new("certs/cert.pem"), X509FileType::PEM);
let _ = context.set_private_key_file(Path::new("certs/privkey.pem"), X509FileType::PEM);
// Launch server
let server = Server::bind_secure("0.0.0.0:1234", &context).unwrap();
// New thread for client
thread::spawn(|| {
let url = Url::parse("wss://127.0.0.1:1234").unwrap(); // Socket URL
let mut client = Client::connect(url).unwrap() // Fetch request
.send().unwrap() // Fetch response
.begin(); // Get client
// Send a hello world message
let _ = client.send_message(&Message::text("Hello, World!"));
});
// Handle server connections
for connection in server {
let connection = connection.unwrap();
// This will panic with "Bad file descriptor"
let _request = connection.read_request().unwrap();
// ...
}
}
All dependencies now compile.
We need to rewrite everything to use the new IO module std::io
, std::net
, etc.
Currently the HTTP request is parsed inside of the library. It would be nice if there was a way to check if an existing hyper Request
is a websocket request, and if so provide a way to "upgrade" it into a websocket connection. This allows using hyper as a HTTP server and accepting websockets on the same port.
This is similar to how the ruby library faye-websocket works. You can check the env (essentially a standard request format) if it is a websocket, and if so "upgrade" it into a websocket connection.
this lib does support socket.io?
As far as I can tell, it does not seem possible to stop the server and close all of the connections cleanly.
Right now you would need some way to signal to each connection to shut them down,then to break out of the for connection in server
you would have to wait for another connection to connect and then break (or make one yourself). But this is very messy. It would be great if there was a shutdown()
method on the server.
According to http://tools.ietf.org/html/rfc6455#section-4.1 connect should take a host, port, resource name, and a secure flag, along with a list of protocols and extensions to be used. Currently, it accepts a Url object.
"A client will need to
supply a /host/, /port/, /resource name/, and a /secure/ flag, which
are the components of a WebSocket URI as discussed in Section 3,
along with a list of /protocols/ and /extensions/ to be used."
extern crate websocket;
use websocket:client::request::Url;
fn main() {
let input = "127.0.0.1:1880";
let url: Url = match input.parse() {
Ok(url) => url,
Err(err) => {
println!("{:?}", err);
}
}
}
Output:
RelativeUrlWithoutBase
However, I don't seem to be able to match on this enum.
If I try, it gives:
src/main.rs:146:17: 146:39 warning: pattern binding `RelativeUrlWithoutBase` is named the same as one of the variants of the type `url::parser::ParseError` [E0170]
src/main.rs:146 Err(RelativeUrlWithoutBase) => {
^~~~~~~~~~~~~~~~~~~~~~
src/main.rs:146:17: 146:39 help: run `rustc --explain E0170` to see a detailed explanation
src/main.rs:146:17: 146:39 help: if you meant to match on a variant, consider making the path in the pattern qualified: `url::parser::ParseError::RelativeUrlWithoutBase`
Trying to use the enum from the url
crate directly gives me:
src/main.rs:14:5: 14:52 error: variant `RelativeUrlWithoutBase` is private
src/main.rs:14 use url::parser::ParseError::RelativeUrlWithoutBase;
Unless I'm missing something, the websocket
library doesn't actually expose this error, the client.rs
file only has
pub use url::Url;
Please let me know if there's a correct way to be able to match on the URL parse errors, thanks! Sorry, I'm relatively new at rust and maybe missed something obvious.
WebSocket connection to 'ws://127.0.0.1:8080/' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received index.html:8
but ok under firefox and midori.
and version 0.9.2 are all ok.
My local build fails with:
native library openssl
is being linked to by more than one package, and can only be linked to by one package
openssl-sys v0.7.0
openssl-sys v0.6.7
Hacking the library to depend on 0.6.7 fixes the build, for now at least.
Hi,
I'm new to rust. I compiled the repo but the main thread is panicking:
Running `target/debug/examples/server`
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 48, message: "Address already in use" } }', ../src/libcore/result.rs:785
note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: Process didn't exit successfully: `target/debug/examples/server` (exit code: 101)
I think a TODO list would be great for contributors. It would be much easier than searching in every file for bugs, typos and lack of documentation.
There have been multiple breaking changes in hyper, see the changelog for more details:
https://github.com/hyperium/hyper/blob/38f40c7f6a17bd33951bbab1adddf542cbb96de6/CHANGELOG.md
In rust and rust-websocket, how to keep the connection for each client persion?
if one client, one thread, can reach 10k connections in single server machine?
TL;DR: Quick (and IMO correct) fix for now is to pin the hyper dependency to the last version before the refactor, 0.5.2. Iron did the same thing while it gets familiar with the changes.
So 1.1 is out. Hyper made some refactorings that changed some stuff around, but mainly with respect to this package it concerns the fact that parse_response
is now in hyper::http::h1
instead of just hyper::http
, and so on. I was working on a fix but the problem I ran into was this at the end of src/server/mod.rs
:
/// Represents a connection to the server that has not been processed yet.
pub struct Connection<R: Read, W: Write>(R, W);
impl<R: Read, W: Write> Connection<R, W> {
/// Process this connection and read the request.
pub fn read_request(self) -> io::Result<Request<R, W>> {
match Request::read(self.0, self.1) {
Ok(result) => { Ok(result) },
Err(err) => {
Err(io::Error::new(io::ErrorKind::InvalidInput, err))
}
}
}
}
This io::Error::new
method requires that the error payload err
'implements' Into<Box<Error + Send + Sync>>
. The error is that the err
is not Sync
or Send
. These kinds of bugs are annoying to track down because it's difficult to tell which field is implicitly breaking the Sync/Send
bounds. If I had to guess, it's also coming from the hyper refactors, so one of the hyper-related error variants is most likely the culprit.
broken by library sha1?
how to fix?
I run example/server.rs ,
in server console, report:
thread '' panicked at 'called Result::unwrap()
on an Err
value: IoError(end of file)', /home/rustbuild/src/rust-buildbot/slave/nightly-linux/build/src/libcore/result.rs:746
and in firefox console:
载入页面时到 ws://127.0.0.1:8080/ 的连接被中断。(connection was aborted when loading page: ws://127.0.0.1:8080/)
every time when I refresh web page in browser and wait some seconds, it occurs.
I have errors with version 0.14:
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value:
DataFrameError("Expected unmasked data frame")', ../src/libcore\result.rs:741
When I try hyper
example Chrome also logs:
WebSocket connection to 'ws://127.0.0.1:2794/' failed:
A server must not mask any frames that it sends to the client.
Any example doesn't work. How to fix?
Env:
64 bit + rustc 1.6.0-nightly (1805bba39 2015-11-26) + Win 10
Hello, I'm seeing the following compiler errors:
$ cargo build
Compiling websocket v0.11.9
/Users/llehmijo/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.9/src/message.rs:59:11: 59:15 error: binary operation `+` cannot be applied to type `collections::vec::Vec<u8>` [E0369]
/Users/llehmijo/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.9/src/message.rs:59 data = data + &dataframe.data[..];
^~~~
/Users/llehmijo/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.9/src/message.rs:106:6: 106:9 error: binary operation `+` cannot be applied to type `collections::vec::Vec<u8>` [E0369]
/Users/llehmijo/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.9/src/message.rs:106 Ok(buf + self.reason.as_bytes())
$ rustc --version
rustc 1.1.0-nightly (dc630d01e 2015-05-09) (built 2015-05-09)
Any way forward from here?
Thanks!
Hi @cyderize,
Thank you first for your work about _rust-websocket_'s project.
I report for you this incident on a _OS X Yosemite_ with the _10.10.2_'s Version:
The fail is bswap: Could not compile
bswap.
> cargo build ()
Updating git repository `https://github.com/cyderize/rust-websocket.git`
Updating registry `https://github.com/rust-lang/crates.io-index`
Downloading openssl-sys v0.5.1
Downloading unicase v0.0.5
Downloading rustc-serialize v0.3.3
Downloading openssl v0.5.1
Downloading hyper v0.3.0
Downloading time v0.1.20
Downloading byteorder v0.2.14
Downloading cookie v0.1.14
Downloading url v0.2.23
Downloading pkg-config v0.3.1
Downloading mime v0.0.10
Downloading bswap v0.1.8
Downloading rand v0.2.0
Compiling bitflags v0.1.1
Compiling bswap v0.1.8
Compiling libc v0.1.3
Compiling matches v0.1.2
/nfs/zfs-student-5/users/2013/adjivas/.cargo/registry/src/github.com-1ecc6299db9ec823/bswap-0.1.8/src/lib.rs:56:15: 56:42 error: mismatched types:
expected `usize`,
found `u32`
(expected usize,
found u32) [E0308]
/nfs/zfs-student-5/users/2013/adjivas/.cargo/registry/src/github.com-1ecc6299db9ec823/bswap-0.1.8/src/lib.rs:56 2.pow(off.trailing_zeros() as u32)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
Compiling rustc-serialize v0.3.3
Compiling gcc v0.3.1
Compiling log v0.2.5
Compiling pkg-config v0.3.1
Compiling unicase v0.0.5
Build failed, waiting for other jobs to finish...
Could not compile `bswap`.
To learn more, run the command again with --verbose.
My tree after:
.
├── Cargo.lock
├── Cargo.toml
├── src
│ └── main.rs
└── target
└── debug
├── build
│ ├── openssl-sys-f4dc33ec05a937b0
│ └── time-8511b46a947a4506
├── deps
│ ├── bswap-3db22c6264f0f04b.d
│ ├── libbitflags-518ea12e21428edd.rlib
│ ├── libgcc-a2129010e6303bbd.rlib
│ ├── liblibc-2a692f33a70517c8.rlib
│ ├── liblog-045aab9d45b4c031.rlib
│ ├── libmatches-68db25b520030534.rlib
│ ├── libpkg-config-4849fc4851dfef8e.rlib
│ ├── librustc-serialize-fb785ec689194073.rlib
│ └── libunicase-9f1a923080f372c3.rlib
├── examples
└── native
I can run both server and client, but when the client starts there is a runtime error:
$ cargo run --example server
Running `target/debug/examples/server`
Connection from 127.0.0.1:58077
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: NoDataAvailable', /Users/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-mac/build/src/libcore/result.rs:729
$ cargo run --example client
Running `target/debug/examples/client`
Connecting to ws://127.0.0.1:2794/
thread '<main>' panicked at 'arithmetic operation overflowed', /Users/endel/.cargo/registry/src/github.com-1ecc6299db9ec823/httparse-0.1.1/src/lib.rs:34
$ rustc --version
rustc 1.1.0-nightly (aecf3d8b6 2015-05-01) (built 2015-05-01)
The docs talk aobut using connect_with with any writer/reader, but no such method is present in the source.
I really would love it if this could build on stable. I would love to help wherever I can.
Some approaches I've seen to getting things to build on stable include:
cfg(feature = "blah")
to conditionally compile pieces of code Compiling websocket v0.11.6
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\lib.rs:4:4: 4:12 error: stability a
ttributes may not be used outside of the standard library
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\lib.rs:4 #![unstable]
^~~~~~~~
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\dataframe.rs:1:4: 1:10 error: stabi
lity attributes may not be used outside of the standard library
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\dataframe.rs:1 #![stable]
^~~~~~
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\result.rs:1:4: 1:10 error: stabilit
y attributes may not be used outside of the standard library
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\result.rs:1 #![stable]
^~~~~~
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\stream.rs:1:4: 1:10 error: stabilit
y attributes may not be used outside of the standard library
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\stream.rs:1 #![stable]
^~~~~~
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\header/mod.rs:1:4: 1:10 error: stab
ility attributes may not be used outside of the standard library
C:\Users\nathan\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.6\src\header/mod.rs:1 #![stable]
^~~~~~
error: aborting due to 5 previous errors
Build failed, waiting for other jobs to finish...
Could not compile `websocket`.
rustc --version
rustc 1.0.0-nightly (2baf34825 2015-04-21) (built 2015-04-22)
Currently I am trying to refactor the idea of a Stream in this library.
A stream should simply be something that can be written to and read from.
The hyper has had some issues with this idea as well, and recently refactored their NetworkStream
which implemented (in my opinion too many) traits: Read + Write + Any + Send + Typeable
, into a Transport
trait which simply implements Read + Write
(and Evented
for mio support).
We are supporting a (maybe strange, maybe normal) use case of being able to split the client into two owned copies (sender and receiver) so they may be used in different threads.
This creates a need for streams to support the ability to clone themselves into two owned copies.
This is OK with TcpStream
, but in SslStream
the try_clone(&self)
function is deprecated in newer versions and will be removed.
Hyper integration is also blocked since Hyper's NetworkStream
and now Transport
do not implement try_clone(&self)
, presumably because of the above reason.
Arc<Mutex<Client<...>>>
The solution as I see it is to no longer support multi-threading as a first class use-case.
If someone needs to use a client on multiple threads they can wrap it in a lock.
I am under the impression that this is how it currently works when one clones a TcpStream
and tries to read and write to it: the kernel has a lock on this file descriptor and blocks calls accordingly. Please correct me if I am wrong. This change would just make the locking more explicit.
This would also allow the Client to not own its stream (which is wanted in the use case of hyper integration).
Multi-threading for servers is still practical though, since each Client
the server creates can be dispatched to worker threads safely.
There will be a method on the Client
called .stream(&self) -> &S
which would return the concrete type of the stream the Client
is using, so it can be cloned by people who want to.
Client
can no longer be split
.Sender
and Receiver
will no longer be able to own/borrow their stream.I'm not sure I fully understand the situation, but let me explain. While running a server, it seems that some laggy clients can slow down the entire accept()
ing process on the server.
According to the gdb
stack trace, it is sometimes stuck as follows:
#0 0x00007ffff72b755d in read () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x000055555561e2fa in net::tcp::TcpStream.Read::read::hcc8bbd2f6c31c9d1o7m ()
#2 0x00005555555af2c4 in websocket::stream::WebSocketStream.Read::read (self=0x7fffffffc750, buf=...) at /home/barosl/.cargo/git/checkouts/rust-websocket-3ef83361cb9b03c6/master/src/stream.rs:19
#3 0x00005555555af052 in fnfn (b=...) at /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/io/buffered.rs:96
#4 0x00005555555aedc3 in websocket::io::with_end_to_cap<closure> (v=0x7fffffffc780, f={union Result<usize, std::io::error::Error> (struct (&mut [u8]))} 0x7fffffffb420)
at /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/io/mod.rs:77
#5 0x00005555555ae94d in websocket::io::buffered::BufReader<R>.BufRead::fill_buf (self=0x7fffffffc750)
at /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/io/buffered.rs:96
#6 0x00005555555adc8c in websocket::http::parse_request<std::io::buffered::BufReader<websocket::stream::WebSocketStream>> (buf=0x7fffffffc750)
at /home/barosl/.cargo/registry/src/github.com-1ecc6299db9ec823/hyper-0.3.2/src/http.rs:313
#7 0x00005555555ad492 in websocket::server::request::Request<R, W>::read (reader=..., writer=...) at /home/barosl/.cargo/git/checkouts/rust-websocket-3ef83361cb9b03c6/master/src/server/request.rs:85
#8 0x00005555555ac426 in websocket::server::Server<'a>::accept (self=0x7fffffffd900) at /home/barosl/.cargo/git/checkouts/rust-websocket-3ef83361cb9b03c6/master/src/server/mod.rs:139
#9 0x00005555555b07a5 in websocket::server::Server<'a>.Iterator::next (self=0x7fffffffd900) at /home/barosl/.cargo/git/checkouts/rust-websocket-3ef83361cb9b03c6/master/src/server/mod.rs:156
As you can see, it is indefinitely waiting for the client to respond with the request header. That means, the following code in src/server/mod.rs
is problematic:
match Request::read(try!(wsstream.try_clone()), try!(wsstream.try_clone())) {
I believe this is because, currently, the request parsing is done in the main thread. To cope with this, the parsing should be delegated to the client thread. But it is not possible, as there is no other way to parse the request manually other than relying on Server::accept()
.
So, I think, there should be two separate methods. One for the TcpStream
acceptance, the other for the usual HTTP parsing. The iterator for Server
should process only the former, and the latter may be processed in a separate thread.
Am I right? What do you think on this?
It would be great if this library supported tokio-rs, it would really ease up the interop and composability of this library.
I'll study the source code and I will file a PR, if I'm confident I know enough about the source to make the changes, and if that feature is desirable enough.
`cargo run
Compiling traitobject v0.0.1
Compiling lazy_static v0.2.1
Compiling unicode-normalization v0.1.2
Compiling libc v0.2.10
Compiling log v0.3.6
Compiling language-tags v0.2.2
Compiling winapi v0.2.6
Compiling semver v0.1.20
Compiling typeable v0.1.2
Compiling pkg-config v0.3.8
Compiling winapi-build v0.1.1
Compiling mime v0.2.2
Compiling ws2_32-sys v0.2.1
Compiling rand v0.3.14
Compiling user32-sys v0.2.0
Compiling openssl-sys v0.7.14
Compiling num_cpus v0.2.13
Compiling rustc_version v0.1.7
Compiling cfg-if v0.1.0
Compiling matches v0.1.2
Compiling kernel32-sys v0.2.2
Compiling unicode-bidi v0.2.3
Compiling byteorder v0.5.1
Compiling bitflags v0.7.0
Compiling rustc-serialize v0.3.19
Compiling unicase v1.4.0
Compiling gcc v0.3.32
Compiling httparse v1.1.2
Compiling gdi32-sys v0.2.0
Compiling hpack v0.2.0
Compiling idna v0.1.0
Compiling solicit v0.4.4
Compiling openssl-sys-extras v0.7.14
Compiling openssl v0.7.14
Compiling url v1.2.0
Build failed, waiting for other jobs to finish...
error: failed to run custom build command for openssl v0.7.14
Process didn't exit successfully: C:\prod\ws\target\debug\build\openssl-5464f8f6e728c35a\build-script-build (
--- stdout
TARGET = Some("x86_64-pc-windows-msvc")
OPT_LEVEL = Some("0")
PROFILE = Some("debug")
TARGET = Some("x86_64-pc-windows-msvc")
debug=true opt-level=0
HOST = Some("x86_64-pc-windows-msvc")
TARGET = Some("x86_64-pc-windows-msvc")
TARGET = Some("x86_64-pc-windows-msvc")
HOST = Some("x86_64-pc-windows-msvc")
CC_x86_64-pc-windows-msvc = None
CC_x86_64_pc_windows_msvc = None
HOST_CC = None
CC = None
TARGET = Some("x86_64-pc-windows-msvc")
HOST = Some("x86_64-pc-windows-msvc")
CFLAGS_x86_64-pc-windows-msvc = None
CFLAGS_x86_64_pc_windows_msvc = None
HOST_CFLAGS = None
CFLAGS = None
running: "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\cl.exe" "/nologo" "/MD" "/Z7"
s\target\debug\build\openssl-5464f8f6e728c35a\out\src\c_helpers.o" "/c" "src/c_helpers.c"
c_helpers.c
src/c_helpers.c(1): fatal error C1083: Cannot open include file: 'openssl/ssl.h': No such file or directory
ExitStatus(ExitStatus(2))
command did not execute successfully, got: exit code: 2
--- stderr
thread '
RUST_BACKTRACE=1
for a backtrace.
`
The link given in the readme to view documentation gives a 404 error.
http://cyderize.github.io/rust-websocket/doc/websocket/
https://github.com/cyderize/rust-websocket/blob/master/examples/server.rs
How do I send received messages to all connected clients in the server? Kind of like a massive open room, where everyone can hear anybody.
Compiling websocket v0.11.7
C:\Users\fuchs_000\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.7\src\ws\util\dataframe.rs:3:5: 3:28 e
rror: unresolved import `std::num::FromPrimitive`. There is no `FromPrimitive` in `std::num`
C:\Users\fuchs_000\.cargo\registry\src\github.com-1ecc6299db9ec823\websocket-0.11.7\src\ws\util\dataframe.rs:3 use std::
num::FromPrimitive;
error: aborting due to previous error
Build failed, waiting for other jobs to finish...
Could not compile `websocket`.
rustc --version
rustc 1.1.0-nightly (90cc83015 2015-04-22) (built 2015-04-23)
Is it possible to have multiple threads use a Sender simultaneously?
I have a thread whose entire purpose is sending a ping-type message, and it worked with the old Client design, but I'm not sure how to transition it into the new Receiver/Sender design (Sender doesn't implement Clone).
this is the best websocket of rust now!
Do you consider to combine with hyper?
thx.
When I run the examples server and autobahn-server they fail in Chome but work in Firefox
The server fails with one of the message below
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: NoDataAvailable', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/result.rs:729
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: IoError(Error { repr: Os(32) })', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/result.rs:729
Chrome's error message is below
WebSocket connection to 'ws://127.0.0.1:2794/' failed: Error during WebSocket handshake: Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
One difference I can see in the request headers is Chrome has client_max_window_bits in its Sec-WebSocket-Extensions header
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Firefox
GET / HTTP/1.1
Host: 127.0.0.1:2794
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: null
Sec-WebSocket-Protocol: rust-websocket
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: lDZ28g1qsvq2+z4hj7hUzQ==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
HTTP/1.1 101 Switching Protocols
Sec-WebSocket-Accept: fhZDselY5dBr8uW+eFXcOtdkUXw=
Connection: Upgrade
Upgrade: websocket
..Hello
Chrome
GET / HTTP/1.1
Host: 127.0.0.1:2794
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: null
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-GB,en;q=0.8
Sec-WebSocket-Key: QUrpS70CwiViTEk5g68sBA==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Protocol: rust-websocket
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: OPF1GnZv5n7IftL0aFw7ijr3v6c=
..Hello
Should be Client::get_{,mut_}receiver. Fixing this will be a breaking change unfortunately :P
The documentation link on https://crates.io/crates/websocket and on the project homepage https://cyderize.github.io/rust-websocket/ is not working:
http://cyderize.github.io/rust-websocket/doc/websocket/ shows a 404.
I'm getting a panic when accepting a new connection using Request.accept()
on server, especially when multiple clients are trying to connect at once.
thread '<main>' panicked at 'called `Option::unwrap()` on a `None` value', /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/option.rs:362
stack backtrace:
1: 0x7f9cfc9b10f4 - sys::backtrace::write::h9babc8795a85a17910C
2: 0x7f9cfc9b4c7f - panicking::on_panic::h87037425aaedfce4thJ
3: 0x7f9cfc9a276a - rt::unwind::begin_unwind_inner::h938edd242c70217e2XI
4: 0x7f9cfc9a2e21 - rt::unwind::begin_unwind_fmt::h73e2fa758231ca8aDWI
5: 0x7f9cfc9b4667 - rust_begin_unwind
6: 0x7f9cfc9e0b64 - panicking::panic_fmt::h4acd4dec7d5ce278Tku
7: 0x7f9cfc9e09e4 - panicking::panic::he2b07ace86a7d60eqju
8: 0x7f9cfc91f898 - option::Option<T>::unwrap::h8919241931690594829
at /home/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/macros.rs:19
9: 0x7f9cfc91aede - server::response::Response<R, W>::new::h4627714234374605650
at /home/barosl/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.2/src/server/response.rs:73
10: 0x7f9cfc91acd8 - server::request::Request<R, W>::fail::h18318390619043582200
at /home/barosl/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.2/src/server/request.rs:152
11: 0x7f9cfc909e78 - server::request::Request<R, W>::accept::h8170096839402963781
at /home/barosl/.cargo/registry/src/github.com-1ecc6299db9ec823/websocket-0.11.2/src/server/request.rs:145
12: 0x7f9cfc8f955e - main::h618e390d4325d3e6maa
at src/main.rs:17
13: 0x7f9cfc9b85d8 - rust_try_inner
14: 0x7f9cfc9b85c5 - rust_try
15: 0x7f9cfc9b67cb - rt::lang_start::h5750d73c7867c0b9ecJ
16: 0x7f9cfc8f99e4 - main
17: 0x7f9cfbad1ec4 - __libc_start_main
18: 0x7f9cfc8f9148 - <unknown>
19: 0x0 - <unknown>
The relevant code seems to be:
/* src/server/response.rs:71-73 */
pub fn new(request: Request<R, W>) -> Response<R, W> {
let mut headers = Headers::new();
headers.set(WebSocketAccept::new(request.key().unwrap()));
Is there a non-blocking way to check if there is an incoming connection and get that connection if there is?
Something like server.accept() but that would return an Option and return None instead of waiting would be nice.
As seen in #54 star-dependencies can cause problems for packages relying on websocket.
Also it's very unlikely that websocket will work with whatever versions its dependencies decide to release.
Would you consider adding explicit version requirements? I could send a PR for that.
Currently as I'm seeing it, an attacker could hold a thread responding to requests hostage as long as they want. I can of course terminate threads after a certain time but this probably has some dangerous side-effects that I don't ever want to happen.
I tried running the "secure server" example at http://cyderize.github.io/rust-websocket/doc/websocket/server/struct.Server.html
but whenever a websocket client connects to the server, the server fails with
Failed to read request (HttpError(HttpTooLargeError))
It works if I use the non-secure server, and my ssl cert works in another application.
Need to find a fix for this.
Also causes validation issues.
For some reason many tests from the autobahn test suite are now failing.
Not sure what exactly has changed that could cause this strange behaviour.
When running cargo build I was getting this error.
failed to run custom build command for `openssl v0.7.6`
Process didn't exit successfully: `/Users/.../Developer/hello_world/target/debug/build/openssl-09576f2f9776fa80/build-script-build` (exit code: 101)
--- stdout
TARGET = Some("x86_64-apple-darwin")
OPT_LEVEL = Some("0")
PROFILE = Some("debug")
TARGET = Some("x86_64-apple-darwin")
debug=true opt-level=0
HOST = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
HOST = Some("x86_64-apple-darwin")
CC_x86_64-apple-darwin = None
CC_x86_64_apple_darwin = None
HOST_CC = None
CC = None
HOST = Some("x86_64-apple-darwin")
TARGET = Some("x86_64-apple-darwin")
HOST = Some("x86_64-apple-darwin")
CFLAGS_x86_64-apple-darwin = None
CFLAGS_x86_64_apple_darwin = None
HOST_CFLAGS = None
CFLAGS = None
running: "cc" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-m64" "-fPIC" "-o" "/Users/.../Developer/hello_world/target/debug/build/openssl-09576f2f9776fa80/out/src/c_helpers.o" "-c" "src/c_helpers.c"
ExitStatus(ExitStatus(256))
command did not execute successfully, got: exit code: 1
--- stderr
src/c_helpers.c:1:10: fatal error: 'openssl/ssl.h' file not found
#include <openssl/ssl.h>
^
1 error generated.
thread '<main>' panicked at 'explicit panic', /Users/.../.cargo/registry/src/github.com-88ac128001ac3a9a/gcc-0.3.25/src/lib.rs:818
Fixed by the following:
$ brew uninstall --force openssl
$ brew install openssl
$ brew link --force openssl
$ cargo clean
$ cargo build
Hope that this saves someone else some time.
Is there a way, or could it be possible to add one, to send messages without having to allocate?
Basically having something like a MessageRef
or using Cow
so an allocation isn't required.
My use-case is I'm sending a pretty big Vec<u8>
to multiple clients at 30 FPS, and right now I have to clone the vector for every client.
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.