yeonyew / vue-stomp-operator

Vue Stomp and SockJS wrapper plugin
Apache License 2.0
0 stars 1 forks source link

Example #10

Open neuralsys opened 2 years ago

neuralsys commented 2 years ago

How to use this with springboot?

Thanks

yeonyew commented 2 years ago

I'm a front-end developer, so I don't know the details, but I can tell you how I did it.

BackEnd Tip

In Spring Boot, websockets through config are handled directly as controllers and services. The config necessary for handling was written as follows.

StompWebSocketConfig implements WebSocketMessageBrokerConfigurer, StompHandler implements ChannelInterceptor StompOutboundHandler implements ChannelInterceptor StompWebSocketConfig implements WebSocketMessageBrokerConfigurer

We used general subscription and broadcast, and to control individual messages, we implemented restful with special context and _mid in header. recommend service must be Returns _mid in the request header

It would be good to refer to the context section below for how to send a message.

FrontEnd Tip

Just I using @stomp package wrapping class

Install Vue Plugin

Vue.use(VueStompOperator, {
  name: 'custom', // when using custom property (like '$custom')
  url: API_ENDPOINT + '/ws',
});

when using custom global vue instance property

declare module 'vue/types/vue' {
  interface Vue {
    $custom: VueStompOperator;
  }
}

context

I used the method normally used in stomps.

send(request): /topic/... receive(response):

send (like restful)

Need to register subscribe before send But the subscribe promise is reached first.

below example

// subscribe bypass callback, i use only `send` promise callback
this.$stomp.subscribe(`/user/app/hello`, undefined, undefined, true);
this.$stomp
    .send(
      '/topic/hello', // endpoint
      {}, // data
      { token: 'TOKEN' }, // custom headers _mid auto bind all message
      null // options
    )
    .then(async (response: any) => {
      //
    })
    .catch((reason: any) => {
      //
    });

subscribe

stomp.subscribe(`/app/${}`, (msg: any) => {
// when callback directly broadcast message
})
neuralsys commented 2 years ago

How do you connect and subscribe.

If I put in mounted this.$stomp.connect(); this.$stomp.subscribe(/user/app/hello, undefined, undefined, true);

It dosen't work, but it works if i connect after

Vue.use(VueStompOperator, { name: 'custom', // when using custom property (like '$custom') url: API_ENDPOINT + '/ws', });

yeonyew commented 2 years ago

Oh, Sorry didn't tell, how to connect.

In my case, I separated the API file separately. When mounted

api.ts

export let stomp: VueStompOperator;

async function onConnect() {
  const helloSub = await stomp.subscribe(
    '/user/app/...',
    (msg: IMessage) => {
     // do anything
    },
    (reason: any) => {
      if (reason === 'UNAUTHORIZED' && process.env.NODE_ENV === 'production') {
        window.location.href = window.origin + '/';
      }
    }
  );
}

function attach(stompOperator: VueStompOperator) {
  stomp = stompOperator;
  stomp.connect(onConnect);
}

export default {
  attach,
};

main.ts

mounted() {
  // ...
  api.attach(this.$stomp);
}

Calling attach when mounted will attempt to connect

Provide props $stomp from instance this.$stomp.connected

neuralsys commented 2 years ago

And when i have multiple components with different topics.

Lets say UserNotifications.vue subscribes to '/user/app/notifications'

And SystemNotifications.vue subscribes to '/user/app/system-notifications'

Do i need api with connecting for each action?

yeonyew commented 2 years ago

No need multiple connection Just divide the topics and /app context according to your needs in request controller. Only broadcasts and individual subscriptions should be well distributed in the service.

If the subscription can be maintained when the component is destroyed, you can use the unsubscribe returned after subscribe.