e-tipsmemo

ごった煮

rust websocket server sender clone

e-tipsmemo.hatenablog.com

e-tipsmemo.hatenablog.com
を組み合わせて、
Serverがlistenするスレッドとは別のスレッドからも、sendしたかった。

extern crate ws;

use ws::{listen, Sender, Handler, Error, ErrorKind, Result, Message, Handshake};

use std::time::Duration;
use std::thread;
use std::sync::mpsc::Sender as TSender;

enum Event{
    Connect(Sender),
    Disconnect,
}

struct Server {
    ws_out: Sender,
    thread_out: TSender<Event>,
}

impl Handler for Server {
    fn on_open(&mut self, _ : Handshake)->Result<()>{
        println!("on_open");
        self.thread_out.send(Event::Connect(self.ws_out.clone()))
            .map_err(|err| {
                Error::new(
                    ErrorKind::Internal,
                    format!("Unable to communicate between threads: {:?}", err),
                )
            })
    }
    fn on_message(&mut self, msg : Message)->Result<()>{
        println!("{:?}", msg);
        Ok(())
    }
}

fn main() {
    let (tx, rx) = std::sync::mpsc::channel();
    let server = thread::spawn(move || {
        listen("192.168.0.14:3000", |out| {
            Server{
                ws_out: out,
                thread_out: tx.clone(),
            }
        }).unwrap();
    });

    if let Ok(Event::Connect(sender)) = rx.recv()
    {
        for i in 0..5{
        sender.send(format!("{}", i));
        thread::sleep(Duration::from_millis(2000));
        }
    }
}

クライアントは前回のjavascriptのままでServerに別スレッドと、Eventをやり取りするSenderを入れておく。
クライアントからアクセスされたらon_openが呼ばれるので、そこでwsのsenderを送ってやることで、
main関数のほうのスレッドはサーバーが持ってるsenderのcloneをもらうことができる。