如何在Svelte中使用Socket.io?

12
我正在尝试将socket.io与Svelte一起使用,最近我开始尝试使用它,这是按照https://svelte.dev/上的说明安装的原始形式。
无论我尝试什么组合,我都无法理解为什么会出现“bundle.js:4497 GET http:// localhost:5000 / socket.io /?EIO = 3& transport = polling& t = N72840H 404(未找到)”错误。在之前的“基本”Node.js服务器上,相关代码如下:
const express = require('express');
const app = express();
const server = http.createServer(app)
const io = require('socket.io')(server,{
    transports: ['websockets', 'polling'],
    upgrade:false,
    cookie:false
});
const sockets = require('./models/socket')(io)

我尝试了许多不同的组合,包括上述各种建议和替代方案,例如:

require('http').Server(app)

为什么要使用.Server()而不是.createServer()?没有人解释过。我已经尝试了appexpressserver或app.listen等多种方法,有些教程/文章中包含这些内容,有些则不包含-我不知道其中是否有任何先决条件。许多示例都有localhost,也有许多没有。有时冒号后面带有数字,有时没有。
在前端(在.svelte文件中),尝试使用import io from 'socket.io-client',在index.html文件中使用cdn,在head中使用<script src="../socket.io/socket.io.js"></script>(没有点、1个点、没有斜杠等)。最后一个不同之处在于在尝试连接io()之前找不到它,这就是持久错误生成的地方。 io()有时被建议作为io.connect()io.connect('localhost')io.connect('localhost:3000 or 8080 or some other)。天晓得为什么。
这与Rollup.js打包工具的工作方式有关吗?我已经四处查找,但没有任何有用的线索。
如果我的帖子缺少细节或信息,请在评论中指出,我将编辑它以提供所需的详细信息。谢谢!

socket.io可以与svelte(和sapper)一起使用。我已经在rollup、polka、socket.io和socket.io-client上使用它了。你在调用server.listen()时使用的是哪个端口? - joshnuss
我已经尝试了3000、5000(本地主机)、3030、8080等端口,但这些似乎太随意了,我无法弄清楚应该对齐哪个端口。你能否解释一下它实际上有什么区别,因为这是我们和许多其他人在工作版本中实现的其中之一,却不了解其实质? - MikeyB
顺便说一句,我通过构建“bundle.js”,然后调用包含socket.io代码的单独的“app.js”文件来使事情工作。所以它可以工作了,但我不知道这是否正常或理想。现在我正在尝试在“package.json”的“script”中按顺序调用它们,以尝试同时获得“livereload”和“nodemon”的便利,而不必对之前的工作方式做出妥协... - MikeyB
你在使用Rollup打包时,是否成功导入了"socket.io-client"?我甚至无法让它工作。 - Tomasz Plonka
我将socket.io放在rollup进程之外,自从第一次找到这个解决方法后就没有再尝试过。 - MikeyB
显示剩余2条评论
1个回答

3
  1. 创建全局存储 export const socket = writable();
  2. 添加实用函数
import { socket } from "../../store";
import {API_URL} from "../../config"

export const getSocket = async () => {
  const script = document.createElement("script");
  script.src = "/socket-3-0-0.js";
  document.head.appendChild(script);
  
  script.onload = () => {
    const client = io(API_URL)
    socket.set(client)
  }
}
  1. 在_layout中调用getSocket方法
<script>
    onMount(async () => {
        getSocket();
    }
</script>
  1. 导入并使用存储
<script>
    import { socket } from "../store";
    $socket?.on("blah", function() {});
</script>

更新:

  1. You can do smth like this in _layout.svelte:

    <script lang="ts">
      function getIoClient(tokens) {
        if (typeof io !== 'undefined') {
          return io(API_URL, {
            transports: ["websocket", "polling", "flashsocket"],
            withCredentials: true,
            query: {
              ...tokens,
            },
          })
        }
      }
    
      async function initSocket() {
        if ($loggedIn) {
          const auth = await getAuth()
    
          socket.set(
            getIoClient({
              id_token: auth?.id_token,
              refresh_token: auth?.refresh_token,
              access_token: auth?.access_token,
              expiry_date: auth?.expiry_date,
            })
          )
        }
      }
    
      async function socketLoaded() {
        await initSocket()
      }
    </script>
    
    <svelte:head>
      {#if $loggedIn}
        <script src="/socket-3-1-3.js" on:load={socketLoaded}></script>
      {/if}
    </svelte:head>
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接