I'm testing ws-rs websockect (not sure if this is the best one), and need my server to send/broadcast any msg it received from any socket to all other sockets, so I created a Vec
to which I add all sockects, this send them one by one, wrote this block:
static mut all_sockets: Vec<&mut Server> = Vec::new();
fn on_message(&mut self, msg: Message) -> Result<()> {
unsafe { all_sockets.push(self); };
println!("Server got message '{}'. ", msg);
// self.out.send(msg)
unsafe {
for ws in all_sockets {
ws.out.send(msg);
}
}
Ok(())
}
But getting this error:
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
--> src/main.rs:45:35
|
45 | unsafe { all_sockets.push(self); };
| ^^^^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the method body at 44:5
--> src/main.rs:44:5
|
44 | / fn on_message(&mut self, msg: Message) -> Result<()> {
45 | | unsafe { all_sockets.push(self); };
46 | | println!("Server got message '{}'. ", msg);
47 | | // self.out.send(msg)
... |
53 | | Ok(())
54 | | }
| |_____^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0312`.
error: Could not compile `ws`.
My full code is:
use ws::{listen, Handler, Message, Request, Response, Result, Sender, CloseCode};
use std::{thread, io};
use std::io::BufRead;
// This can be read from a file
static INDEX_HTML: &'static [u8] = br#"
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<pre id="messages"></pre>
<form id="form">
<input type="text" id="msg">
<input type="submit" value="Send">
</form>
<script>
var socket = new WebSocket("ws://" + window.location.host + "/ws");
socket.onmessage = function (event) {
var messages = document.getElementById("messages");
messages.append(event.data + "\n");
};
var form = document.getElementById("form");
form.addEventListener('submit', function (event) {
event.preventDefault();
var input = document.getElementById("msg");
socket.send(input.value);
input.value = "";
});
</script>
</body>
</html>
"#;
struct Server {
out: Sender,
}
static mut all_sockets: Vec<&mut Server> = Vec::new();
impl Handler for Server {
fn on_message(&mut self, msg: Message) -> Result<()> {
unsafe { all_sockets.push(self); };
println!("Server got message '{}'. ", msg);
// self.out.send(msg)
unsafe {
for ws in all_sockets {
ws.out.send(msg);
}
}
Ok(())
}
fn on_close(&mut self, code: CloseCode, reason: &str) {
unsafe { all_sockets.retain(|&x| x != self); }
match code {
CloseCode::Normal => println!("The client is done with the connection."),
CloseCode::Away => println!("The client is leaving the site."),
_ => println!("The client encountered an error: {}", reason),
}
}
fn on_request(&mut self, req: &Request) -> Result<(Response)> {
// Using multiple handlers is better (see router example)
match req.resource() {
// The default trait implementation
"/ws" => Response::from_request(req),
// Create a custom response
"/" => Ok(Response::new(200, "OK", INDEX_HTML.to_vec())),
_ => Ok(Response::new(404, "Not Found", b"404 - Not Found".to_vec())),
}
}
}
fn main() {
let my_addr = "127.0.0.1:8080";
let mut me = ws::WebSocket::new(|out| Server { out }).unwrap();
me.listen(my_addr).unwrap();
}