Node ws 与 React Native - ws.send 不是函数

发布于 2025-01-20 09:13:05 字数 4828 浏览 0 评论 0原文

我开始将 websockets 与 ws 一起使用。到目前为止一切都很好。当这个问题发生时,我正在玩 ws 并反应本机。我能够在客户端和服务器之间建立连接,但无法使用 ws.send() 方法发送消息。我正在构建一个简单的聊天应用程序,其中只有特定用户才能接收消息。

客户端

import * as React from 'react';
import { Text, View, StyleSheet, TextInput, Button, ScrollView } from 'react-native';

const setws = (path) => {
  ws = new WebSocket(path);
  return ws;
}

export default function App() {
 

  const [serverState, setServerState] = React.useState('Loading...');
  const [messageText, setMessageText] = React.useState('');
  const [disableButton, setDisableButton] = React.useState(true);
  const [inputFieldEmpty, setInputFieldEmpty] = React.useState(true);
  const [serverMessages, setServerMessages] = React.useState([]);

  const [ws, setws] = React.useState('');  

  React.useEffect(() => {
    
    const ws = new WebSocket('ws://ip-address:8080');
    const serverMessagesList = [];
    
  
    ws.onopen = () => {
      console.log("connection opened")
      setServerState('Connected to the server')
      setDisableButton(false);
    };

    ws.onclose = (e) => {
      console.log("connection closed")
      setServerState('Disconnected. Check internet or server.')
      setDisableButton(true);
    };

    ws.onerror = (e) => {
      setServerState(e.message);
    };

    ws.onmessage = (e) => {
      serverMessagesList.push(e.data);
      setServerMessages([...serverMessagesList])
    };    
  }, [])

  const submitMessage = (ws) => {
    ws.send(messageText);
    setMessageText('')
    setInputFieldEmpty(true)
  };

  return (
    <View style={styles.container}>
      <View style={{
        height: 30,
        backgroundColor: '#eeceff',
        padding: 5
      }}>
        <Text>{serverState}</Text>
      </View>

      <View style={{
        backgroundColor: '#ffeece',
        padding: 5,
        flexGrow: 1
      }}>
        <ScrollView>
          {
            serverMessages.map((item, ind) => {
              return (
                <Text key={ind}>{item}</Text>
              )
            })
          }
        </ScrollView>
      </View>

      <View style={{
        flexDirection: 'row',

      }}>
        <TextInput style={{
            borderWidth: 1,
            borderColor: 'black',
            flexGrow: 1,
            padding: 5,
          }} 
          placeholder={'Add Message'} 
          onChangeText={text => {
            setMessageText(text)
            setInputFieldEmpty(text.length > 0 ? false : true)  
          }}
          value={messageText}
         />
        <Button
         onPress={submitMessage}
         title={'Submit'} 
         disabled={disableButton || inputFieldEmpty}
        />
      </View>
      
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#ecf0f1',
    paddingTop: 30,
    padding: 8,
  },
  
});

服务器

const express = require("express");
const app = express();
const http = require("http");
const WebSocket = require("ws");
const server = http.createServer(app);

const wss = new WebSocket.Server({ server });

const url = require('url');

//This function generates ids
wss.getUniqueID = function () {
    function s4() {
        return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
    }
    return 'USER' + '-' + s4() + '-' + s4();
};

//This function checks if the client is a driver. If not gives an id to the client
wss.checkClient = function (ws) {
    if (ws.id) {
        console.log(ws.id);
    } else {
        if (ws.upgradeReq.url.slice(1)) {
            ws.id = ws.upgradeReq.url.slice(1)}
        else {
            ws.id = wss.getUniqueID();
        }
    }
}
server.listen(8080,'ip-address', () => {
  console.log("Listening to port 8080");
});

wss.on("connection", function connection(ws, req) {
    //Check the id for driver
    wss.checkClient(ws);
    
    console.log("new client connected");

    //We have a connection
    ws.on("message", function incoming(message, isBinary) {
        
        if (ws.id.length > 3) {
            wss.clients.forEach(function each(client) {
                //Check if the user is connected
                if (client.readyState === WebSocket.OPEN && client.id == 123) {
                    
                    //Send the message to the user
                    client.send(message.toString());
                }
            });
        } 
    });
});

app.get("/", (req, res) => {
  res.send("Hello World!");
});

我认为问题出在客户端,但我还没有弄清楚。

I am starting to use websockets with ws. So far everything was good. I was playing with ws and react native when this problem occured. I am able to establish connection between client and server but i can't send messages using the ws.send() method. I am building a simple chat app where only specific users can recieve messages.

Client

import * as React from 'react';
import { Text, View, StyleSheet, TextInput, Button, ScrollView } from 'react-native';

const setws = (path) => {
  ws = new WebSocket(path);
  return ws;
}

export default function App() {
 

  const [serverState, setServerState] = React.useState('Loading...');
  const [messageText, setMessageText] = React.useState('');
  const [disableButton, setDisableButton] = React.useState(true);
  const [inputFieldEmpty, setInputFieldEmpty] = React.useState(true);
  const [serverMessages, setServerMessages] = React.useState([]);

  const [ws, setws] = React.useState('');  

  React.useEffect(() => {
    
    const ws = new WebSocket('ws://ip-address:8080');
    const serverMessagesList = [];
    
  
    ws.onopen = () => {
      console.log("connection opened")
      setServerState('Connected to the server')
      setDisableButton(false);
    };

    ws.onclose = (e) => {
      console.log("connection closed")
      setServerState('Disconnected. Check internet or server.')
      setDisableButton(true);
    };

    ws.onerror = (e) => {
      setServerState(e.message);
    };

    ws.onmessage = (e) => {
      serverMessagesList.push(e.data);
      setServerMessages([...serverMessagesList])
    };    
  }, [])

  const submitMessage = (ws) => {
    ws.send(messageText);
    setMessageText('')
    setInputFieldEmpty(true)
  };

  return (
    <View style={styles.container}>
      <View style={{
        height: 30,
        backgroundColor: '#eeceff',
        padding: 5
      }}>
        <Text>{serverState}</Text>
      </View>

      <View style={{
        backgroundColor: '#ffeece',
        padding: 5,
        flexGrow: 1
      }}>
        <ScrollView>
          {
            serverMessages.map((item, ind) => {
              return (
                <Text key={ind}>{item}</Text>
              )
            })
          }
        </ScrollView>
      </View>

      <View style={{
        flexDirection: 'row',

      }}>
        <TextInput style={{
            borderWidth: 1,
            borderColor: 'black',
            flexGrow: 1,
            padding: 5,
          }} 
          placeholder={'Add Message'} 
          onChangeText={text => {
            setMessageText(text)
            setInputFieldEmpty(text.length > 0 ? false : true)  
          }}
          value={messageText}
         />
        <Button
         onPress={submitMessage}
         title={'Submit'} 
         disabled={disableButton || inputFieldEmpty}
        />
      </View>
      
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#ecf0f1',
    paddingTop: 30,
    padding: 8,
  },
  
});

Server

const express = require("express");
const app = express();
const http = require("http");
const WebSocket = require("ws");
const server = http.createServer(app);

const wss = new WebSocket.Server({ server });

const url = require('url');

//This function generates ids
wss.getUniqueID = function () {
    function s4() {
        return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
    }
    return 'USER' + '-' + s4() + '-' + s4();
};

//This function checks if the client is a driver. If not gives an id to the client
wss.checkClient = function (ws) {
    if (ws.id) {
        console.log(ws.id);
    } else {
        if (ws.upgradeReq.url.slice(1)) {
            ws.id = ws.upgradeReq.url.slice(1)}
        else {
            ws.id = wss.getUniqueID();
        }
    }
}
server.listen(8080,'ip-address', () => {
  console.log("Listening to port 8080");
});

wss.on("connection", function connection(ws, req) {
    //Check the id for driver
    wss.checkClient(ws);
    
    console.log("new client connected");

    //We have a connection
    ws.on("message", function incoming(message, isBinary) {
        
        if (ws.id.length > 3) {
            wss.clients.forEach(function each(client) {
                //Check if the user is connected
                if (client.readyState === WebSocket.OPEN && client.id == 123) {
                    
                    //Send the message to the user
                    client.send(message.toString());
                }
            });
        } 
    });
});

app.get("/", (req, res) => {
  res.send("Hello World!");
});

I think the problem lays on the client side, but i haven't figured it out yet.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光匆匆的小流年 2025-01-27 09:13:05
  1. 您的 sumbitMessage 函数创建自己的 ws - 它不使用您的 ws 状态。
  2. 您使用 setws 两次 - 一次作为“全局”函数,一次作为 setState 函数。

只需将您创建的 websocket 存储在状态中,然后单击拉动状态即可发送功能。就像这样:

export default function App() {
 

  .....

  const [ws, setWs] = React.useState('');  

  React.useEffect(() => {
    
    const newWs = new WebSocket('ws://ip-address:8080');
    const serverMessagesList = [];
    
  
    newWs.onopen = () => {
      console.log("connection opened")
      setServerState('Connected to the server')
      setDisableButton(false);
    };

    newWs.onclose = (e) => {
      console.log("connection closed")
      setServerState('Disconnected. Check internet or server.')
      setDisableButton(true);
    };

    newWs.onerror = (e) => {
      setServerState(e.message);
    };

    newWs.onmessage = (e) => {
      serverMessagesList.push(e.data);
      setServerMessages([...serverMessagesList])
    };   
   setWs(newWs)  // store created websocket in ws state 
  }, [])

  const submitMessage = (sock) => {
    sock.send(messageText);
    setMessageText('')
    setInputFieldEmpty(true)
  };

.......

        <Button
         onPress={() => submitMessage(ws)}
         title={'Submit'} 
         disabled={disableButton || inputFieldEmpty}
        />
  1. Your sumbitMessage function creates its own ws - it is not using your ws state.
  2. You use setws twice - once as "global" function, once as setState function.

Just store your created websocket in state and on click pull the state the send function. Just like this:

export default function App() {
 

  .....

  const [ws, setWs] = React.useState('');  

  React.useEffect(() => {
    
    const newWs = new WebSocket('ws://ip-address:8080');
    const serverMessagesList = [];
    
  
    newWs.onopen = () => {
      console.log("connection opened")
      setServerState('Connected to the server')
      setDisableButton(false);
    };

    newWs.onclose = (e) => {
      console.log("connection closed")
      setServerState('Disconnected. Check internet or server.')
      setDisableButton(true);
    };

    newWs.onerror = (e) => {
      setServerState(e.message);
    };

    newWs.onmessage = (e) => {
      serverMessagesList.push(e.data);
      setServerMessages([...serverMessagesList])
    };   
   setWs(newWs)  // store created websocket in ws state 
  }, [])

  const submitMessage = (sock) => {
    sock.send(messageText);
    setMessageText('')
    setInputFieldEmpty(true)
  };

.......

        <Button
         onPress={() => submitMessage(ws)}
         title={'Submit'} 
         disabled={disableButton || inputFieldEmpty}
        />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文