【问题标题】:Proper way of using WebSockets with React Native在 React Native 中使用 WebSocket 的正确方法
【发布时间】:2017-10-20 15:31:44
【问题描述】:

我是 React Native 的新手,但对 React 非常熟悉。正如我在文档中看到的那样,作为初学者,我希望在云服务器和使用 websockets 的 react-native 之间建立连接。不幸的是,没有像样的例子可以帮助我。到目前为止,这就是我所拥有的一切:

import React, { Component } from 'react';

import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Button
} from 'react-native';

export default class raspberry extends Component {
  constructor(props) {
    super(props);

    this.state = { open: false };
    this.socket = new WebSocket('ws://127.0.0.1:3000');
    this.emit = this.emit.bind(this);
  }

  emit() {
    this.setState(prevState => ({ open: !prevState.open }))
    this.socket.send("It worked!")
  }

  render() {

    const LED = {
      backgroundColor: this.state.open ? 'lightgreen' : 'red',
      height: 30,
      position: 'absolute',
      flexDirection: 'row',
      bottom: 0,
      width: 100,
      height: 100,
      top: 120,
      borderRadius: 40,
      justifyContent: 'space-between'

    }

    return (
      <View style={styles.container}>
        <Button
          onPress={this.emit}
          title={this.state.open ? "Turn off" : "Turn on"}
          color="#21ba45"
          accessibilityLabel="Learn more about this purple button"
        />
        <View style={LED}></View>
      </View>
    );
  }

  componentDidMount() {
    this.socket.onopen = () => socket.send(JSON.stringify({ type: 'greet', payload: 'Hello Mr. Server!' }))
    this.socket.onmessage = ({ data }) => console.log(JSON.parse(data).payload)
  }

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

AppRegistry.registerComponent('raspberry', () => raspberry);

一切正常,但是当我按下按钮发送消息时,这是我得到的错误:

无法发送消息。未知的 WebSocket id 1

我还用一个 js 客户端进行了测试,一切都很顺利..看看我如何修复这个问题或一些我可以解决的示例源。

【问题讨论】:

  • 你是不是不小心没有打开还没打开的socket?
  • 我来自 socket.io 那里关闭套接字不是一件事,但是对于 ws 这真的可能是一件事。我回家后会尝试关闭它们,请给小费!
  • 只是想知道,您不使用 socket.io 有什么原因吗?
  • 收到一个未“验证的错误”,知道如何解决吗?

标签: reactjs react-native websocket


【解决方案1】:

修改代码

socket.send(JSON.stringify({ type: 'greet', payload: 'Hello Mr. Server!' }))

this.socket.send(JSON.stringify({ type: 'greet', payload: 'Hello Mr. Server!' }))

它应该可以工作。

这是我要测试的代码,基于您的代码和 RN 0.45(以及由 create-react-native-app 生成的项目),连接到公共 websocket 服务器wss://echo.websocket.org/,在我的 android 上它工作正常,我可以按下按钮后查看 websocket 服务器的回显消息。

import React, { Component } from 'react';

import {
    StyleSheet,
    Text,
    View,
    Button
} from 'react-native';

export default class App extends React.Component {

    constructor() {
        super();

        this.state = {
            open: false
        };
        this.socket = new WebSocket('wss://echo.websocket.org/');
        this.emit = this.emit.bind(this);
    }

    emit() {
        this.setState(prevState => ({
            open: !prevState.open
        }))
        this.socket.send("It worked!")
    }

    componentDidMount() {
        this.socket.onopen = () => this.socket.send(JSON.stringify({type: 'greet', payload: 'Hello Mr. Server!'}));
        this.socket.onmessage = ({data}) => console.log(data);
    }

    render() {

        const LED = {
            backgroundColor: this.state.open
            ? 'lightgreen'
            : 'red',
            height: 30,
            position: 'absolute',
            flexDirection: 'row',
            bottom: 0,
            width: 100,
            height: 100,
            top: 120,
            borderRadius: 40,
            justifyContent: 'space-between'
        }

        return (
            <View style={styles.container}>
                <Button onPress={this.emit} title={this.state.open
        ? "Turn off"
        : "Turn on"} color="#21ba45" accessibilityLabel="Learn more about this purple button"/>
                <View style={LED}></View>
            </View>
        );
    }
}


const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF'
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10
    },
    instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5
    }
});

【讨论】:

  • 这是在原始帖子中发现并修复实际错误的答案。
  • 收到一个未“验证的错误”,知道如何解决吗?
【解决方案2】:

根据documentation,您需要将状态connected 添加到您的组件中。并且仅当 connected 状态为真时才发送任何内容。

export default class raspberry extends Component {
  constructor(props) {
    super(props);
    this.state = {
      open: false,
      connected: false
    };
    this.socket = new WebSocket('ws://127.0.0.1:3000');
    this.socket.onopen = () => {
      this.setState({connected:true})
    }; 
    this.emit = this.emit.bind(this);
  }

  emit() {
    if( this.state.connected ) {
      this.socket.send("It worked!")
      this.setState(prevState => ({ open: !prevState.open }))
    }
  }
}

【讨论】:

  • 这似乎行得通,我一回家就测试它
  • 收到一个未“验证的错误”,知道如何解决吗?
【解决方案3】:

我做了一些研究后发现WebSocket应该是

new WebSocket("ws://10.0.2.2:PORT/")

其中10.0.2.2 表示localhost

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-20
    • 1970-01-01
    • 2019-07-17
    • 2022-12-22
    • 2021-04-17
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    相关资源
    最近更新 更多