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

Websockets do not work #22

Open
chanced opened this issue Oct 21, 2021 · 16 comments
Open

Websockets do not work #22

chanced opened this issue Oct 21, 2021 · 16 comments

Comments

@chanced
Copy link

chanced commented Oct 21, 2021

Using the following code, I cannot establish websocket connections:

import Fastify from "fastify";
import wsPlugin from "fastify-websocket";

export const server = Fastify();
server.register(wsPlugin);
server.get("/", { websocket: true }, (ws, req) => {
	console.log(req);
	ws.socket.on("message", (msg) => {
		console.log(msg.toString());
		ws.socket.send("hi from server");
	});
});

if (process.env.NODE_ENV === "production") {
	server.listen(3000);
}

If I run the server directly, it works fine.

vite.config.ts:

import { defineConfig } from "vite";
import { VitePluginNode } from "vite-plugin-node";
export default defineConfig({
	server: {
		port: 3000,
	},
	plugins: [
		...VitePluginNode({
			adapter: "fastify",
			appPath: "./src/server.ts",
			exportName: "server",
			tsCompiler: "esbuild",
		}),
	],
});
@axe-me
Copy link
Owner

axe-me commented Oct 21, 2021

hi @chanced thank you for reporting this. I have to figure out a way to support websocket

@chanced
Copy link
Author

chanced commented Oct 21, 2021

@axe-me no problem. Thanks for publishing the package.

I'm just going to roll with esbuild for that package. It makes more sense anyway. I figured I'd let you know, regardless.

@dhkatz
Copy link

dhkatz commented Nov 13, 2021

Websockets don't seem to work with Express as well

@shaif-dorIT
Copy link

I think it work in production at least for me, I used express.js and socket.io for example (I took the base code from YT called The net ninja repo link: https://github.com/iamshaunjp/websockets-playlist).

what I did is:

  1. created websocket.ts that export function addWebSocketHandler:
import { Server } from 'http'
import { Server as WSServer } from 'socket.io'

export function addWebSocketHandler(server: Server) {
	const io = new WSServer(server, { allowEIO3: true })
	io.on('connection', (socket) => {
		console.log('made socket connection', socket.id)

		// Handle chat event
		socket.on('chat', function (data) {
			io.sockets.emit('chat', data)
		})

		// Handle typing event
		socket.on('typing', function (data) {
			socket.broadcast.emit('typing', data)
		})
	})
}
  1. imported it on app.ts:
import { addWebSocketHandler } from './websocket'
  1. then added it to production if case:
if (process.env.NODE_ENV === 'production') {
	const server = app.listen(3000, () => console.log(`server run on: http://localhost:3000`))
	if (process.env.WS === 'true') {  // a check I added to make sure there is WS handler we want to add in.
		addWebSocketHandler(server)
	}
}

As for ViteDevServer,
I think this is a good way to add it only need to add support in ViteNodeConfig for that.
like adding new key called wsPath like the appPath key in the config.

That we can call the function from the file provided in the config and add it to vite dev server although I fairly new to vite so I do not know how to accomplish that.

@jordanranson
Copy link

The WS library also doesn't work. For now I've been using the below work around which uses nodemon to build and run the app on file change. This is obviously not ideal because I lose out on HMR, and have to run the app in production mode locally, but its better than having to manually restart Vite everytime I make a change.

Here is the work around, replace your npm run dev with the following command:
nodemon --exec \"vite build && node dist/main.js\" -e ts --ignore dist/

@datyin
Copy link

datyin commented Mar 28, 2022

Any news on this issue?

@francipvb
Copy link

Hllo,

I think this is not too difficult to work on.

Just like the viteNodeApp export key, there can be added another export default key that receives the web server built by vite. Then the user code can be do anything with it.

Of course, the function should be called every time the HMR runs.

@francipvb
Copy link

Not sure if it can be done, but here is my suggestion.

@chanced chanced changed the title Websockets don't seem to work, at least with Fastify Websockets do not work Jul 12, 2022
@romanzy313
Copy link

I have the same issue. In order for websockets to work the server needs to handle upgrade request, and since vite uses it for live reload, our own ws implementation does not work. I think vite recieves the upgrade event and it does not propograte to our code. It may be very hard to solve this issue, as rewriting vite's behavior is a no go.

Vite is an absolute blessing upon js and ts community, and bringing it to the server is the next step. Typescript project setup is always a pain, and this project solves all the issues.

In the meantime use nodemon.

Hope this can be resolved someday.

@Shyam-Chen
Copy link

Shyam-Chen commented Oct 7, 2022

For a workaround: nodemon + vite-node

package.json:

// ...
"dev": "nodemon -e \"ts,mts,json\" -x \"vite-node src/server.ts\" -w \"src/**/*\" -i \"**/__tests__/**\"",
"build": "vite build",
"preview": "node dist/server.mjs",
"test": "vitest --coverage",
// ...

vite.config.ts:

// ...

export default defineConfig({
  // ...
  build: {
    ssr: './src/server.ts',
  },
  // ...
});

My template is here.

@svicalifornia
Copy link

@Shyam-Chen What's the benefit of running vite-node if you're just going to restart it via nodemon whenever any of the source files changes?

@Shyam-Chen
Copy link

Shyam-Chen commented Jan 18, 2023

@svicalifornia No benefit of vite-node in nodemon. I just want to support WebSockets in development.

// ...
"dev": "vite",
"dev:ws": "nodemon -e \"ts,mts,json\" -x \"vite-node src/server.ts\" -w \"src/**/*\" -i \"**/__tests__/**\"",
"build": "vite build",
"preview": "node dist/server.mjs",
"test": "vitest --coverage",
// ...

@Shyam-Chen
Copy link

Shyam-Chen commented Feb 3, 2023

Ref: vitest-dev/vitest#2334

Use vite-node -w src/server.ts

server.listen({
  host: process.env.HOST,
  port: process.env.PORT,
});
    
if (import.meta.hot) {
  import.meta.hot.on('vite:beforeFullReload', () => {
    server.close();
  });

  import.meta.hot.dispose(() => {
    server.close();
  });
}
- "dev": "nodemon -e \"ts,mts,json\" -x \"vite-node src/server.ts\" -w \"src/**/*\" -i \"**/__tests__/**\"",
+ "dev": "vite-node -w src/server.ts",

Reload is faster than nodemon.

@srmagura
Copy link

srmagura commented May 3, 2023

Probably not necessary, but I created another minimal repro of this problem before I found this issue.

Feel free to use it for testing: https://github.com/srmagura/ws-test-vite

@daleal
Copy link

daleal commented May 15, 2023

I had a similar problem when using vite-plugin-node, koa and socket-io and kinda made it work. My solution looks like this (I use the express adapter because it expects a plain http server unlike the koa adapter apparently):

// vite.config.ts

export default defineConfig({
  server: {
    port: 3000,
  },
  plugins: [
    ...VitePluginNode({
      adapter: 'express',
      appPath: 'src/main.ts',
      exportName: 'serverListener',
    }),
  ],
});
// src/main.ts

import Koa from 'koa';
import { createServer } from 'http';
import * as constants from '@/constants';

const application = new Koa();

const server = createServer(application.callback());
const io = new SocketIoServer(server, { /* options */ });
io.on('connection', (socket) => {
  // do somethin
});

// Workaround to allow websockets on development using vite-plugin-node
export const serverListener = server.listeners('request')[0];

if (constants.common.ENVIRONMENT === 'production') {
  server.listen(3000);
  console.log('Running application on http://localhost:3000');
}

I haven't been able to establish connections to ws://localhost:3000 yet, but I can now use the polling transport of socket-io on the dev server, which I previously could not do at all, so I suspect my issue is a different one. Hope someone finds a use for this!

@tamilv
Copy link

tamilv commented Feb 25, 2024

        // Add Web Socket Configuration
        await app.register(require('@fastify/websocket'), {
            options: {
                maxPayload: 1048576,
                server: app.server
            },
        });
        
        it is working well in local. once I deployed and configured SSL then it is not working 

anyone please help me

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