Skip to content

Websockets do not work #22

Open
Open

Description

@chanced

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",
		}),
	],
});

Activity

  1. axe-me commented on Oct 21, 2021

    @axe-me
    Owner

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

  2. chanced commented on Oct 21, 2021

    @chanced
    Author

    @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.

  3. dhkatz commented on Nov 13, 2021

    @dhkatz

    Websockets don't seem to work with Express as well

  4. shaif-dorIT commented on Feb 17, 2022

    @shaif-dorIT

    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.

  5. jordanranson commented on Feb 26, 2022

    @jordanranson

    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/

  6. datyin commented on Mar 28, 2022

    @datyin

    Any news on this issue?

  7. francipvb commented on Jul 3, 2022

    @francipvb

    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.

  8. francipvb commented on Jul 3, 2022

    @francipvb

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

  9. changed the title [-]Websockets don't seem to work, at least with Fastify[/-] [+]Websockets do not work[/+] on Jul 12, 2022
  10. romanzy313 commented on Jul 17, 2022

    @romanzy313

    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.

  11. Shyam-Chen commented on Oct 7, 2022

    @Shyam-Chen

    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.

  12. svicalifornia commented on Jan 17, 2023

    @svicalifornia

    @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?

  13. Shyam-Chen commented on Jan 18, 2023

    @Shyam-Chen

    @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",
    // ...
  14. Shyam-Chen commented on Feb 3, 2023

    @Shyam-Chen

    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.

  15. srmagura commented on May 3, 2023

    @srmagura

    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

  16. daleal commented on May 15, 2023

    @daleal

    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!

  17. tamilv commented on Feb 25, 2024

    @tamilv
            // 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions