Skip to content
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

Channels aren't working anymore with socket.io-client #892

Closed
chainyo opened this issue Oct 22, 2024 · 6 comments
Closed

Channels aren't working anymore with socket.io-client #892

chainyo opened this issue Oct 22, 2024 · 6 comments
Milestone

Comments

@chainyo
Copy link

chainyo commented Oct 22, 2024

Description

The channels feature is not working with the most recent loco-rs v0.10.1 version and socketioxide v0.14.0 as presented in the documentation and/or in the chat-rooms example.

To Reproduce

I git cloned the chat-rooms example repository and updated the both dependencies to reproduce the recent setup by updating the dependencies:

git clone https://github.com/loco-rs/chat-rooms.git
cd chat-rooms
  • Update the cargo.toml file
loco-rs = { version = "0.10.1", default-features = false, features = [
  "cli",
  "channels",
] }
...
tokio = { version = "1.33.0", features = ["rt-multi-thread"]}
  • Update the src/app.rs file:
use async_trait::async_trait;
use loco_rs::{
    app::{AppContext, Hooks},
    bgworker::Queue,
    boot::{create_app, BootResult, StartMode},
    controller::{channels::AppChannels, AppRoutes},
    environment::Environment,
    task::Tasks,
    Result,
};

use crate::channels;

pub struct App;
#[async_trait]
impl Hooks for App {
    fn app_name() -> &'static str {
        env!("CARGO_CRATE_NAME")
    }

    fn app_version() -> String {
        format!(
            "{} ({})",
            env!("CARGO_PKG_VERSION"),
            option_env!("BUILD_SHA")
                .or(option_env!("GITHUB_SHA"))
                .unwrap_or("dev")
        )
    }

    async fn boot(mode: StartMode, environment: &Environment) -> Result<BootResult> {
        create_app::<Self>(mode, environment).await
    }

    fn routes(ctx: &AppContext) -> AppRoutes {
        AppRoutes::empty()
            .prefix("/api")
            .add_app_channels(Self::register_channels(ctx))
    }

    fn register_channels(_ctx: &AppContext) -> AppChannels {
        let messages = channels::state::MessageStore::default();

        let channels: AppChannels = AppChannels::builder().with_state(messages).into();
        channels.register.ns("/", channels::application::on_connect);
        channels
    }

    async fn connect_workers(ctx: &AppContext, queue: &Queue) -> Result<()> {
        Ok(())
    }

    fn register_tasks(_tasks: &mut Tasks) {}
}
  • Update the src/bin/main.rs:
use loco_rs::cli;
use chat_rooms::app::App;

#[tokio::main]
async fn main() -> loco_rs::Result<()> {
    cli::main::<App>().await
}
  • Update the src/channels/state.rs by adding this Clone implementation:
impl Clone for MessageStore {
    fn clone(&self) -> Self {
        let messages = tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap().block_on(async {
            self.messages.read().await.clone()
        });
        MessageStore {
            messages: RwLock::new(messages),
        }
    }
}

Expected Behavior

The messages aren't transmitted through websocket as the frontend can't connect to the backend anymore.

It seems that some url parameters have been added to the uri path when looking at the logs

2024-10-22T08:02:55.818183Z DEBUG http-request: tower_http::trace::on_response: finished processing request 
latency=0 ms status=404 http.method=GET http.uri=/socket.io/?EIO=4&transport=polling&t=PApG1h6 
http.version=HTTP/1.1 http.user_agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like
 Gecko) Chrome/128.0.0.0 Safari/537.36 environment=development request_id=402c7c43-42ee-4441-979c-86ef1c1966d4

I'm not sure how we could update the backend to accept the connection and allow this: http.uri=/socket.io/?EIO=4&transport=polling&t=PApG1h6

@chainyo chainyo closed this as completed Oct 22, 2024
@chainyo chainyo reopened this Oct 22, 2024
@Sillyvan
Copy link
Contributor

Sillyvan commented Oct 27, 2024

+1 Something about the routing seems broken here.

Really just seems like Axum didnt register that /socket.io/ path and just returns the fallback which of course leads to an error.

Edit: Removing the Fallback or even disabling static sadly dosent fix the issue either

@Sillyvan
Copy link
Contributor

@jondot Making sure this isnt overseen because it seems to be an actual bug.

From what i can tell it started from V0.8. I even have the assumption its this commit here: dbea6b1

The chatroom example also stops compiling from that version on.
here the errors:

error[E0277]: the trait bound {closure@src/channels/application.rs:21:9: 21:85}: MessageHandler<LocalAdapter, _> is not satisfied
--> src/channels/application.rs:21:9
|
19 | socket.on(
| -- required by a bound introduced by this call
20 | "join",
21 | / |socket: SocketRef, Data::(room), store: Statestate::MessageStore| async move {
22 | | tracing::info!("Received join: {:?}", room);
23 | | let _ = socket.leave_all();
24 | | let _ = socket.join(room.clone());
25 | | let messages = store.get(&room).await;
26 | | let _ = socket.emit("messages", Messages { messages });
27 | | },
| |_________^ the trait MessageHandler<LocalAdapter, _> is not implemented for closure {closure@src/channels/application.rs:21:9: 21:85}

error[E0277]: the trait bound {closure@src/channels/application.rs:32:9: 32:88}: MessageHandler<LocalAdapter, _> is not satisfied
--> src/channels/application.rs:32:9
|
30 | socket.on(
| -- required by a bound introduced by this call
31 | "message",
32 | / |socket: SocketRef, Data::(data), store: Statestate::MessageStore| async move {
33 | | tracing::info!("Received message: {:?}", data);
34 | |
35 | | let response = state::Message {
... |
43 | | let _ = socket.within(data.room).emit("message", response);
44 | | },
| |_________^ the trait MessageHandler<LocalAdapter, _> is not implemented for closure {closure@src/channels/application.rs:32:9: 32:88}

error[E0277]: the trait bound MessageStore: Clone is not satisfied
--> src/app.rs:44:71
|
44 | let channels: AppChannels = AppChannels::builder().with_state(messages).into();
| ---------- ^^^^^^^^ the trait Clone is not implemented for MessageStore
| |
| required by a bound introduced by this call

i managed to make it compile by wrapping the RwLock with an Arc. and giving the MessageStore the Clone derive but now you cant connect to it anymore.

@ShaneM123
Copy link

Any Update or workaround on this? I'm hoping to use channels

@Sillyvan
Copy link
Contributor

Sorry for tagging again @kaplanelad @jondot but can we get some info about this?
I have seen a few people on discord asking about this as well. just making sure it didn't go under the radar

@jondot jondot added this to the 0.13.1 milestone Nov 20, 2024
@kaplanelad
Copy link
Contributor

Hey @Sillyvan,
I'm will investigate this issue for the next release

@kaplanelad
Copy link
Contributor

After reviewing our implementation of socketioxide within the Loco.rs framework, we've decided to remove support for channels.

You can see a working example of char-room implementation based on loco and socketioxide with initializer here: https://github.com/loco-rs/chat-rooms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants