1. Introduction

Two days ago, the blogger wrote an article about the realization of front-end project in the separation of the front and back end of the blog. The realization of front-end project in the separation of the front and back end of the blog is mostly referring to the book “Spring Boot+Vue full stack development Practice”. In fact, the blogger was also confused when writing that article, it was pure handling of the code. Then, I am not good at using Vuex and Vue Rooter in Vue. I used the weekend to separate the front and back end of the chat function in the micro personnel project to realize a short time. I also had a preliminary understanding and use of Vuex and Vue Rooter. Here are some of my own understandings during the implementation process.

2.WebScoket

2.1 introduction

WebSocket is a network transport protocol that enables full-duplex communication over a single TCP connection and is located at the application layer of the OSI model.

2.2 advantage

  • Since WebSocket connections are created on port 80 (WS) or 443 (WSS), the same port used for HTTP, virtually all firewalls do not block WebSocket connections;
  • WebSocket uses HTTP protocol for handshake, so it can be naturally integrated into web browsers and HTTP servers.
  • With this protocol, both the server and client can know when a message starts or arrives

2.3 use

It can be applied to anything involving instant communication:

  • Chat online on the web
  • Multiplayer online games
  • Online stock website
  • An online instant news site
  • Hd video streaming
  • Communication between application clusters
  • Real-time monitoring of remote system/software status and performance

2.4 the actual combat

Introduction of depend on

< the dependency > < groupId > org. Webjars < / groupId > < artifactId > stomp - websocket < / artifactId > < version > 2.3.3 < / version > </dependency>Copy the code

Let’s take a look at WebSocket with two simple demos:

2.4.1 Group Chat small demo

First of all, we implemented a group chat function: the implementation of group chat is relatively simple, no need to consider the recipient, just need to subscribe to a message at an address, the code part of the blogger only show some key parts, the project code link see the end of the article.

Start by defining the Spring Security class configuration:

public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    PasswordEncoder passwordEncoder(a) {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("javaboy")
                .password("123")
                .roles("admin")
                .and()
                .withUser("sang")
                .password("123")
                .roles("user");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .rememberMe()
                .and()
                .csrf().disable()
                .sessionManagement()
                .maximumSessions(1)// The maximum number of logins is 1
                .maxSessionsPreventsLogin(true); }}Copy the code

Configure two users “xiesuper”, “sang” and assign permissions to them. For SpringSecurity, if you are not familiar with SpringSecurity, please refer to this article.

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/queue"."/topic");
        /*registry.setApplicationDestinationPrefixes("/app"); * / // This is a prefix and can be added as required
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        /*registry.addEndpoint("/chat").withSockJS(); * /
        registry.addEndpoint("/ws/endpointChat").withSockJS(); }}Copy the code

Code explanation:

  • We added the /ws/endpointChat connection point so that we could use this link to connect to the server’s WebSocket on a web page. But then there’s withSockJs, what is that? SockJs is a WebSocket communication JS library. Spring automatically supports this JS library in the background. That is to say, if we use SockJs, then we do not need to configure the background.
  • The second method, configureMessageBroker, basically sets up the message broker, which is the address on the page to subscribe to with JS, and the address from which our server sends messages to the WebSocket side.

Define the Controller class

@Controller
public class GreetingController {
    @Autowired
    SimpMessagingTemplate simpMessagingTemplate;


    @MessageMapping("/hello")// Implement group chat
    public void greeting(Message message) {
        simpMessagingTemplate.convertAndSend("/topic/greetings", message);//
    }


    @MessageMapping("/chat")// Implement group chat
    public void chat(Principal principal, Chat chat){
// Get sender information
        chat.setFrom(principal.getName());

        simpMessagingTemplate.convertAndSendToUser(chat.getTo(),"/queue/chat",chat);// Destination is the address from which the message is sent, and the front-end subscribe function subscribes the message


    }
Copy the code

Code interpretation

  • The convertAndSend function first is the address to send the Message, and the second is a custom Message class
  • ConvertAndSendToUser takes the first argument to the receiver, the second argument to the address to send the message, and the third argument to a custom Chat class

The front-end implementation

Key front-end code chat.html:

stompClient.send('/hello', {},JSON.stringify({'name': $("#name").val(),'content': $("#content").val()}))
Copy the code

Code explanation:

  • Pass parameters to the Controller class greeting function, encapsulated in a Message class
function connect() {
        if(! $("#name").val()) {
            return;
        }
        var socket = new SockJS('/ws/endpointChat');
        stompClient = Stomp.over(socket);
        stompClient.connect({}, function (success) {
            setConnected(true);
            stompClient.subscribe('/topic/greetings'.function (msg) {// Defined message
                showGreeting(JSON.parse(msg.body)); }); })}Copy the code

Code explanation:

  • /ws/endpointChat corresponds to the join point added in the WebSocket configuration class. Subscribe function is the message subscription, and parameter 1 is the message sending address defined in Controller. The second parameter is the callback function, MSG is the information obtained

2.4.2 Chat small Demo

The configuration for group chat is similar to that for single chat, given in the Controller class above, and the front page is similar to that for group chat:

 $("#send").click(function () {
            stompClient.send('/chat', {}, JSON.stringify({
                'to': $("#to").val(),
                'content': $("#content").val()
            }))
        })
Copy the code
function connect() {
        var socket = new SockJS('/ws/endpointChat');
        stompClient = Stomp.over(socket);
        stompClient.connect({}, function (success) {
            setConnected(true);
            stompClient.subscribe('/user/queue/chat', function (msg) {
                showGreeting(JSON.parse(msg.body));
            });
        })
        
Copy the code

Notice that the first argument to the subscribe function is preceded by user, which is a Websocket specification for point-to-point sending

Demonstrate the GIF:

OK, the following completed two small demo, think you also have a certain understanding of the use of WebSocket, the following content is combined with Vue and its plug-ins vuecli,vuex, VUE-Router this chat room for certain integration.

2.5Vue interface design

First, initialize the project, CNPM vuex,vue-router (vue-router can choose whether to install during the initialization project) for detailed reference

The realization of front end project in front end separation project

The project structure is as follows:Configure the proxyTable


proxyTable: {
      '/': {
        target: 'http://localhost:8089'.changeOrigin: true.pathRewrite: {
          '^ /': ' '}},'/ws/*': {
        target: 'ws: / / 127.0.0.1:8089'.ws: true}},Copy the code

The routing configuration

export default new Router({
  routes: [{path: '/home'.name: 'home'.component: HelloWorld,
      hidden: true.meta: {
        requireAuth: true
      },
      children: [{path: '/chat'.name: 'message'.component: Chat,
          hidden: true.meta: {
            keepAlive: false.requireAuth: true}}]}})Copy the code

Code interpretation

  • Is it SPA design, so routing needs to be configured? It can be seen that we only configured one page, which may be a little confusing for friends. Let’s go to the interface first:

We type /home in the address bar to get the following interface, which is designed in helloworld.vue:

<template> <div class="hello"> <div style="display: flex; align-items: center; margin-right: 7px"> <el-badge style="margin-right: 30px" > <i class="fa fa-bell-o" @click="goChat" style="cursor: Pointer "> chat < / I > < / el badge - > < / div > < the router - the view > < / router - the view > < / div > < / template >Copy the code

Note that router-view: the component to which the route matches is rendered here.

The children node is configured with the path of /chat during the routing configuration, which is as follows:

When we click on the chat room, we call goChat() :

methods:{
    goChat(){
      this.$router.push({path: '/chat'}); }}Copy the code

The current URL path changes and then renders the component at the router-view tag.

Chat. Vue code

<template> <div> <el-tabs v-model="activeName" @tab-click="handleClick" style="margin-top: 10px"> <el-tab-pane Label =" System notification" name="notification">< NF ></ NF ></el-tab-pane> < El-tab-pane Label =" Buddy chat" name="chat"><fc></fc></el-tab-pane> </el-tabs> </div> </template> <script> import FriendChat from '@/components/chat/FriendChat' import Notification from '@/components/chat/Notification' export default { data() { return { activeName: 'notification' }; }, methods: { handleClick(tab, event) { console.log(tab, event); } }, components:{ 'fc':FriendChat, 'nf':Notification } }; </script>Copy the code

This time we just realize friends chat, system notification is only for the future development of an interface

Key code implementation is in friendchat. vue, as well as store folder index. Js, basic slightly complex code has annotations, friends can download the source code to learn.

Chat room implementation:About a pothole encountered when using vuex:

To access this.$Store property in a Vue component, you need to provide a created store for the Vue instance. Vuex provides a mechanism to “inject” the store from the root component to all child components in the form of store options:

new Vue({
  el: '#app'.store: store,
})
Copy the code

SessionStorge differs from Window.localStorge:

  • window.sessionStorge
  1. The life cycle is to close the browser window. After the window is closed, the data is lost and stored in the browser memory.
  2. Storage and use of key-value pair form.
  3. Data on the same window and page can be shared.
  • window.localStorge
  1. The life cycle is permanent, unless manually deleted, close the browser and open the data will still exist, the data is stored on the hard disk.

  2. The key-value pair form is stored for use.

  3. Data can be shared in multiple Windows (pages) (the same browser).

Download the source code