New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Discussion: becoming lightweight and feature-full (through hyper, mio, net2 and more) #58
Comments
@illegalprime, it's awesome that you're contributing - thanks so much! The only other thing I can think of is specifically supporting With regards to custom headers though, I'm not sure what you're referring to there. I mean, you can already access My concern with not using hyper is that we'd probably end up having to use string-type or binary headers, which I'm not really a fan of. I quite like hyper's headers, and I wish that they were in their own crate. I'm looking forward to seeing your API ideas. |
Not a problem! Just want to get a foot in in the open source community. ClientsCurrentlylet url = Url::parse("ws://127.0.0.1:1234").unwrap(); // Get the URL
let request = Client::connect(url).unwrap(); // Connect to the server
let response = request.send().unwrap(); // Send the request
response.validate().unwrap(); // Ensure the response is valid
let mut client = response.begin(); // Get a Client This might not be great for a few reasons:
ProposalOverview of OptionsA list of possible websocket configuration options
Semantics
This is also more consistent with the standard websocket client implementation (except in that one Possible API No. 1: Option Strutcs// `connect` here means immediately start the handshaking process
let mut client = Client::connect("wss://echo.example.org", &Opts {
// An optional ssl context, other than the default
ssl_context: None,
// a list of protocols
protocols: ["image/jpeg", "echo"],
// a list of extensions
extensions: ["gzip"],
// the stream to talk over other than the default.
// either an (Read, Write) or a Read + Write
stream: None,
.. Default::default()
})
.unwrap();
// `new` means do not start the handshake and return an intermediate client
let client_template = Client::new("wss://echo.example.org", Default::default());
// .. do some work
let mut client = client_template.begin().unwrap(); // .begin takes a borrow of self Possible API No. 2: Builder Syntax// Gradually "build" a websocket and connect
let mut client = Client::build("wss://echo.example.org")
.protocols(["echo"])
.extensions(["deflate"])
// you can get what `new` does for free by not calling this:
.connect()
.unwrap();
// Maybe a Client::connect() and Client::new() for convenience ServersCurrentlyThe server implementation is good, but it doesn't allow you to integrate with other stuff like #53 mentions. Can you tell I'm getting tired of writing by now? ProposalBasically many things will implement With HyperServer::http("0.0.0.0:0").unwrap().handle(move |request, response| {
match request.into_ws() {
Ok(upgrade) => {
if upgrade.protocols().contains("echo") {
let mut client = upgrade.accept().unwrap();
// some ws stuff
} else {
upgrade.reject();
}
},
Err((request, _)) => {
// some http stuff
},
}
}); ImplementationThe trait: pub trait IntoWs {
fn into_ws(self) -> Result<WsUpgrade, (Self, Error)>;
} The pub struct WsUpgrade {
// Note: consuming self
fn accept(self) -> Result<Client> {}
fn reject(self) -> Result<()> {}
// Some convenience methods
fn protocols() -> &[&str] {}
fn extensions() -> &[&str] {}
fn origin() -> &str
/* probably more stuff */
} Default ServerNow the server that comes with the package will just automatically call let server = Server::bind("127.0.0.1:1234").unwrap();
for connection in server.connections() {
if upgrade.protocols().contains("echo") {
let mut client = upgrade.accept().unwrap();
// some ws stuff
} else {
upgrade.reject();
}
} We can just let people implement Miscellaneous
Wrapping UpI think this API will last a while and is reasonable, what do you think about it? |
And another thing, I'm thinking pub struct Client<S, D> {
stream: S,
_dataframe: PhantomData<fn(D)>,
}
pub trait Stream {
type R: Read;
type W: Write;
fn reader(&mut self) -> &mut Self::R;
fn writer(&mut self) -> &mut Self::W;
fn split(self) -> (Self::R, Self::W);
}
impl<S> Stream for S
where S: Read + Write {
/* ... */
}
impl<R, W> Stream for (R, W)
where R: Read,
W: Write {
/* ... */
} The implementation in the crate will actually create a |
@illegalprime I really like your proposal, I think it would really improve the library a lot! For the client API, I'm leaning towards API No. 2 (builder pattern) because The Thanks for all your hard work! |
|
Any new²+s on this? Happy to help out, as I need rust experience. |
Hey @avitex I just finished with my exams, so I'll be able to put more attention towards this. |
@illegalprime Sure am. Keep in mind I am relatively new to the rust eco-system, however that's the point of working with someone who is experienced. |
@avitex I think a straightforward task on this ticket is to begin work on the client builder. Another thing that I think should be straightforward but maybe not it to merge
Let me know what you'd be interested in and of course ask if you have any questions. Reach me by email (listed on my profile) or mention me somewhere on GitHub, you can also start a PR against my fork and we can discuss your progress there :) |
It's done. |
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
supportprotocols
Pain Points:
hyper
is overkill. still not 100% sure.http-muncher
orhttparse
+ 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.
The text was updated successfully, but these errors were encountered: