Node.js 切换到Typescript时套接字io客户端问题

Node.js 切换到Typescript时套接字io客户端问题,node.js,reactjs,typescript,express,sockets,Node.js,Reactjs,Typescript,Express,Sockets,我正在尝试为MERN stack+Socket.io使用一个模板,然后迁移到Typescript。当我将客户端更改为Typescript时,我遇到了问题 问题:我的客户端从socket.io-client ping无法到达服务器,而且我似乎不知从何处收到了pong 服务器:对于服务器端,我将cd放入服务器并运行npm start=node dist/app.js 服务器代码:dist/app.ts import { Mongoose } from "mongoose"; im

我正在尝试为MERN stack+Socket.io使用一个模板,然后迁移到Typescript。当我将客户端更改为Typescript时,我遇到了问题

问题:我的客户端从socket.io-client ping无法到达服务器,而且我似乎不知从何处收到了pong

服务器:对于服务器端,我将cd放入服务器并运行npm start=node dist/app.js

服务器代码:dist/app.ts

import { Mongoose } from "mongoose";
import express from "express";
import { Socket } from "socket.io";
const app=express();
const http = require('http').Server(app);
const path = require('path');
const io = require('socket.io')(http);
const uri = process.env.MONGODB_URI|| "";
const port = process.env.PORT || 5000;
const mongoose: Mongoose = require('mongoose');


mongoose.connect(uri, {
  useUnifiedTopology: true,
  useNewUrlParser: true,
});

app.use(express.static(path.join(__dirname, '..', 'client', 'build')));

io.on('connection', (socket: Socket) => {

    socket.on('ping',(msg)=>{
        console.log(msg)
        socket.emit('pong')
    })

 console.log("A user has connected")
});

http.listen(port, () => {
  console.log('listening on *:' + port);
});
客户:我有一个样板react项目,代码在Client/src/app.tsx中。我运行npm start=react脚本启动

客户端代码:

import React, {useState, useEffect} from 'react';
import './App.css';
import config from './config';
const io=require('socket.io-client')
const PORT=config[process.env.NODE_ENV].endpoint
const socket = io(PORT);
console.log(PORT)
const App: React.FC = () => {

  const [clicked,setClicked] = useState(false)
  useEffect(()=> {
    socket.on('pong', ()=>
    console.log("pong"));
  });
   
  function handleClick() {
    console.log("click")
    
    socket.emit('ping')
  }

  return (
    <div className="App">
      <button onClick={()=> handleClick()}>
        {clicked? "ON": "OFF"}
      </button>
      
    </div>
  );
}

export default App;

输出:

在客户端控制台上,我得到我的端口(在package.json中是我的代理)是http://localhost:5000. 我也会很慢地(每隔15秒)收到一系列“砰”的声音,与我的点击完全无关。真的不清楚这是怎么发生的,希望我正在做一些非常愚蠢的事情

在服务器上,每当我连接时,我只看到“一个用户已连接”,没有乒乓

我尝试了很多方法,包括使用非功能组件,但都没有效果。我不清楚如何调试它,它只是在过去工作过。显然,服务器和客户机正在通信,但套接字实际上没有


欢迎大家提出建议

ping
pong
是保留的
Socket.IO
事件(,在页面底部),这意味着您不能自己使用它们。您应该改为使用一些其他事件名称


至于它以前为什么起作用。。。我完全不知道。

我想用一些字节回答了pong以意外方式返回的原因,但我认为您得到多个pong的原因可能是因为
useffect
没有依赖项列表(这会导致效果在每次更新时运行)。可以多次调用
socket.on
,从而在
pong
事件上多次运行
console.log

此外,我个人从未尝试过在组件生命周期之外进行
io.connect
(或
io(url)
操作)。不确定这是否与此有关,但我会将
io.connect
放在
useffect
中,并使用
useRef
存储套接字。比如:

const socketRef=useRef(未定义);
useffect(()=>{
常量套接字=io(端口);
socketRef.current=插座;
socket.on('server',()=>console.log(“server”);
}, []);

哇,好吧,这对我来说是个新闻。为了清楚和透明,我的意思是类似的工作之前。不是乒乓球。我把它简化为这个简单的例子,因为它“更容易”。我试试别的,谢谢!是的,就是这样。事实上,我以前的项目太大了,无法一件一件地转向tsx,所以我只是剥离了功能,并尝试从我能想到的最简单的例子开始重新构建它。真有趣,我居然挑了这些禁赛项目!非常感谢,这只虫子害了我两个周末!谢谢你的建议。我还同时实施了上述建议,效果非常好。
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": false,
    "jsx": "react"
  },
  "include": [
    "src"
  ]
}