简体   繁体   English

不能在 stomp 客户端订阅中使用“this” - React

[英]Can't use “this” in stomp client subscribe - React

I have my Spring-Boot service setup so I can send messages through websocket to my browser and it works.我有我的 Spring-Boot 服务设置,所以我可以通过 websocket 将消息发送到我的浏览器并且它可以工作。

  //@MessageMapping
    @RequestMapping(value = "/notify")
    @SubscribeMapping("/notification")
    @SendTo("/topic/notification")
    public String sendNotification() throws Exception {
        sendMessage();
        return "Request to update Tanks has been sent!";
    }

    public void sendMessage() {
        this.messagingTemplate.convertAndSend("/topic/notification", "IT WORKS");
    }

Here's the console log from chrome:这是来自 chrome 的控制台日志:

<<< MESSAGE
destination:/topic/notification
content-type:text/plain;charset=UTF-8
subscription:sub-1519225601109-13
message-id:f2qodiqn-8
content-length:8

IT WORKS

I want to be able to receive a message from the service and update the state in react, so, that it refetches from the backend.我希望能够从服务接收消息并更新反应状态,以便它从后端重新获取。 This is what my client looks like:这是我的客户的样子:

var socket = new SockJS("http://localhost:6667/refresh");
var stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
  console.log('connected: ' + frame);
  stompClient.subscribe('/topic/notification', function(notification){
    console.log(notification.body);
    //this.showNotification(JSON.parse(notification.body).content);
    //this.showNotification(notification.body);
  })
}, function(err) {
  console.log('err', err);
});

And the fetch in componentDidMount()componentDidMount()的提取

fetch(`http://localhost:6666/front/objects`)
    .then(result=>result.json())
    .then(fuelTanks=>this.setState({fuelTanks}))
    .catch(function(err) {
      console.log('Could not fetch: ' + err.message);
    }
  )

I can't use this.showNotification(notification.body) , hence I can't set the state to be able to refetch my objects.我无法使用this.showNotification(notification.body) ,因此我无法将状态设置为能够重新获取我的对象。 I tried making methods outside the class but then I can't use anything from the main class.我尝试在类之外创建方法,但后来我无法使用主类中的任何方法。

Is there a way to make react run componentDidMount again, or better, just access the fetch method in my class when I get a message from spring through the websocket?有没有办法让 react 再次运行 componentDidMount ,或者更好的是,当我通过 websocket 从 spring 收到消息时,只访问我类中的 fetch 方法?

Like this:像这样:

componentDidMount(){

  var socket = new SockJS("http://192.168.1.139:8610/refresh");
  var stompClient = Stomp.over(socket);
  stompClient.connect({}, function(frame) {
    console.log('connected: ' + frame);
    stompClient.subscribe('/topic/notification', function(notification){
      refetchTanks(); // call fetch tanks -> can't use "this"
    })
  }, function(err) {
    console.log('err', err);
  });

Thanks!谢谢!

I know, it is a bit old question, but since it pops every time when you search for stomp issue, i thought of answering it.我知道,这是一个有点老的问题,但是由于每次搜索 stomp 问题时它都会弹出,所以我想回答它。 The way to access this in callbacks is to bind callbacks with this first, then the whole of object can be accessed in the callback.在回调中访问 this 的方法是先将回调与 this 绑定,然后可以在回调中访问整个对象。 Example:示例:

    connectCallBack(){
  this.setState({loading:false})

 }
 errorCallback=()=>{

 }

componentDidMount() {


axios.post('http://localhost:8080/subscribe', null, { params: {
deviceId
}})
.then(response => response.status)
.catch(err => console.warn(err));

const socket = new SockJS('http://localhost:8080/test');
const stompClient = Stomp.over(socket);

//stompClient.connect();
stompClient.connect( {}, this.connectCallBack, this.errorCallback);

If see above code both callbacks can access this.如果看到上面的代码,两个回调都可以访问它。

I tried everything to be able to use my class methods and the state in stompClient's .subscribe method.我尝试了所有能够使用我的类方法和 stompClient 的.subscribe方法中的状态。 I was able to connect and reconnect if the service died, nevertheless it wasn't working.如果服务死机,我能够连接并重新连接,但它无法正常工作。

I decided to use react-stomp , which worked.我决定使用react-stomp ,它起作用了。 I could use a class method in onMessage=... .我可以在onMessage=...使用类方法。 This is what my code looks like:这是我的代码的样子:

<SockJsClient 
  url = 'http://localhost:8610/refresh/'
  topics={['/topic/notification']} 
  onConnect={console.log("Connection established!")} 
  onDisconnect={console.log("Disconnected!")}
  onMessage={() => this.update()}  <------ this method performs a new GET 
                                           request
  debug= {true}
/> 

I also had to send the message in a specific way on the server side, since I was getting a JSON error when sending a string.我还必须在服务器端以特定方式发送消息,因为我在发送字符串时收到 JSON 错误。

this.messagingTemplate.send("/topic/notification", "{"text":"text"}");

<<< MESSAGE
destination:/topic/notification
content-type:text/plain;charset=UTF-8
subscription:sub-0
message-id:aaylfxl4-1
content-length:49

{

  "text": "text"

}

It currently works, but I am curious if there are other, better solutions to this issue.它目前有效,但我很好奇是否有其他更好的解决方案来解决这个问题。

EDIT: a much better solution here !编辑: 这里有一个更好的解决方案! Use the code from the first post and create a variable before connect to be able to access this like this var self = this;从第一篇文章使用的代码,并创建一个变量之前connect到能够访问this类似这样的var self = this; , then just access is as self.update() after subscribe ! ,然后在subscribe后访问就像self.update()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM