matallui / artico

Artico - WebRTC made simple
https://artico.dev
MIT License
22 stars 2 forks source link

Integrating Artico Server with other Web frameworks #11

Closed lynxionxs closed 6 days ago

lynxionxs commented 1 week ago

Using Artico/server as the main server seems wasteful. Since it's role is to be a signal server using socket.io. Socket.io integrates next to other web frameworks. Artico should be able to integrate into other Nodejs web frameworks, and be called when needed by the application. How does one go about integrating Artico/server into other web frameworks without it having to have a port passed into it, and just use the main web server connection of the web framework?

import Fastify from "fastify";
import { ArticoServer } from "@rtco/server";

const port = 3200;

const fastify = Fastify({
    logger: true,
});

// Index
fastify.get("/", function (request, reply) {
    reply.send({ hello: "world" });
});

// Start Artico server
fastify.get("/start-signal-server", function (request, reply) {
    console.log("Starting Artico server...");

    const server = new ArticoServer({ debug: 4 });
        // ...

    reply.send({});
});

// Run the main server
fastify.listen({ port: port }, function (err, address) {
    if (err) {
        fastify.log.error(err);
        process.exit(1);
    }
    console.log(`Server is now listening on ${address}`);
});
matallui commented 1 week ago

Hey @lynxionxs! First of all, thank you for using Artico and for opening the feature request. I agree we need to add a way to integrate with existing web servers. I'll look into adding this feature on the next release. You're also welcome to contribute to it, if you feel like it! :)

lynxionxs commented 1 week ago

Thank you. Such a feature will be really helpful. Great project 👍

matallui commented 1 week ago

@lynxionxs I've added an httpServer option to the ArticoServer constructor that would allow you to attach the Artico socket.io server to an existing HTTP server instance. Take a look and let me know if that would solve your issue.

If not, let me know if you have any suggestions on how this should integrate with existing servers or web frameworks.

lynxionxs commented 1 week ago

@matallui That is great, thanks for the feature. Though, i don't think this project will be good for my usecase. The application server will have it's own websocket implementation, and it conflicts with Artico's socket.io instance. Also in Artico there's not a way to set custom server configs, as can be done in PeerJS. For when not using same domain.

const myPeer = new Peer({
    secure: true,
    host: "localhost",
    port: 3200,
    path: "/peerjs",
});
matallui commented 1 week ago

@lynxionxs I can take a look at PeerJS and see what they do. How do you think this interface should look like? Do you have any ideas on how this would work?

I will take a stab at it as soon as I find some time, but trying to understand exactly what you're requesting.

lynxionxs commented 1 week ago

@matallui basically, my usecase requires for the Node web server to have it's own websocket functionality, to act as a chat and realtime data point for users of the NuxtJS Webapp. Where the P2P part comes in is for direct video calls between 2 users. That's where something like Artico and PeerJS comes in to handle that part. PeerJS was fine at first, but when the Web server needed it's own Websocket instance it conflicted with PeerJS's Websocket. That forced socket.io to use long polling instead.

I was thinking if Artico exposed it's socket.io instance to the Web server it may work. That would also mean that Artico would have to be in a socket.io namespace like io.of("/rtco") and leave room for the Web server to use the rest of socket.io instance. But that would go against the design of Artico as it is now. For now, i'm seeing if i can piggy-back off of PeerJS's Websocket instance. Since the P2P video calls is more wanted now, rather than the chat and realtime Webapp data.

I don't see Artico have a way to connect to another server when say the client is on https://localhost:3000 and the Web server at https://localhost:4000. PeerJS gives those options on the client side.

The Artico equivalent options could maybe look like this:

const rtco = new Artico({
  debug: 1, 
  id: undefined, 
  signaling: undefined, 
  rtcConfig: undefined, 
  // From PeerJS server connection example
  secure: true,
  host: "localhost",
  port: 4000,
  path: "/rtco",
});

I know this is far from what Artico is designed to be. From a P2P signal server meant to run on it's own, to an integration with other Web servers and playing nice with other frameworks/libs.
Sorry, it may be a bit much.

matallui commented 1 week ago

@lynxionxs So ArticoServer already exposes the underlying socket.io Server instance. So, I wonder if this could already work for your case, unless I'm not understanding what you're trying to do.

What if you did something like:

// Artico's socket.io signaling server
// You can also pass your own HTTP server to it, if you have one already running
const articoServer = new ArticoServer();

// Obtain the socket.io `Server` instance
const io = articoServer.server;

// Since Artico uses the default namespace, you could use different namespaces for your other functionality?
io.of("/chat").on("message", () => {});

// ...

It would also be very easy to add a namespace option to the ArticoServer constructor, so we can use the provided namespace instead of the default one. I can add that if you think that's useful.

Let me know your thoughts!

lynxionxs commented 1 week ago

@matallui oh, i didn't know Artico already exposed its underlying socket.io Server instance. Thanks. Your suggestions about the namespaces will help. I'm wondering if i create an ArticoServer instance and use it's io for say namespace /chat , that it won't persist a P2P connection. Because the P2P should be activated when needed. And if ArticoClient also exposes Socket.io instance ?

Other than that it's just a few things to make it work. * Passing in a custom server into Artico constructor* Using ArticoServer Socket.io instance* Adding external host domain in ArticoClient constructor like PeerJS

Had to find hacky ways around PeerJS. Thanks for the suggestions.

matallui commented 6 days ago

@lynxionxs I believe Artico already provides a way for you to pass your own host domain. The Artico client constructor allows you to pass in a Signaling implementation, and Artico gives you access to SocketSignaling (Artico's default signaling implementation).

So, you could do something like:

const rtco = new Artico({
  signaling: new SocketSignaling({ url: "https://your.server" }),
});

Let me know if that works for you!

lynxionxs commented 6 days ago

Thanks. Then that will solve all those issues i had. I've settled on MediaSoup for now, but will play around with Artico wehn able to. Thanks for the help, hope this project grows well.

matallui commented 6 days ago

@lynxionxs Glad that works for you! I'm closing this issue for now. Also, consider giving the project a star, so we can hopefully get a little more visibility and reach. I'd love for more people to start using and contribute to the project :)