【原创】SocketIO使用Vue前端+Java后端做一个后端向浏览器的实时推送功能

一、创建Socket.io的服务端

官网写的已经非常详细了:https://socket.io/get-started/chat/

这里为了省事,直接晒代码了:

1、创建package.json

{
  "name": "test_socketio",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.15.2",
    "socket.io": "^2.3.0"
  }
}

当然,我的项目名就叫test_socketio,大家可以随意命名。记得创建后npm install

2、创建index.html

这个是一个发送的调试界面,能够验证服务是否启动成功,页面代码来自官网的demo

<!doctype html>
<html>
<head>
  <title>Socket.IO chat</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font: 13px Helvetica, Arial; }
    form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
    form input { border: 0; padding: 10px; width: 90%; margin-right: 0.5%; }
    form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
    #messages { list-style-type: none; margin: 0; padding: 0; }
    #messages li { padding: 5px 10px; }
    #messages li:nth-child(odd) { background: #eee; }
  </style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
  <input id="m" autocomplete="off" /><button>Send</button>
</form>

<script src="/socket.io/socket.io.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(function () {
  var socket = io();
  $('form').submit(function(e){
    e.preventDefault(); // prevents page reloading
    socket.emit('chat message', $('#m').val());
    $('#m').val('');
    return false;
  });
  socket.on('chat message', function(msg){
    $('#messages').append($('<li>').text(msg));
  });
});
</script>

</body>
</html>

3、创建index.js

不说别的,直接上代码:

var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
  console.log('a user connected');

  socket.on('disconnect', () => {
    console.log('user disconnected');
  });

  socket.on('ServerIterationBroadcastSend', (data) => {
    // INFO: Dechert: 2020/8/13 接收后端发来的广播推送请求 
    const dataObj = JSON.parse(data)
    io.emit(`WebIterationBroadcastReceive`, dataObj.content) // INFO: Dechert: 2020/8/13 向web端发送从Java服务端收到的内容 
  })

  socket.on('ServerIterationPointSend', (data) => {
    // INFO: Dechert: 2020/8/13 接收后端发来的针对单一用户的推送请求 
    const dataObj = JSON.parse(data)
    const userId = dataObj.userId
    io.emit(`WebIterationPointReceive_${userId}`, dataObj.content) // INFO: Dechert: 2020/8/13 向web端发送从Java服务端收到的内容  
  })
});

io.emit('some event', {someProperty: 'some value', otherProperty: 'other value'}); // This will emit the event to all connected sockets

http.listen(3000, () => {
  console.log('listening on *:3000');
});

注意:我这边后端的项目名叫ServerIteration,后端迭代项目,作为后端经验积累,不停更新迭代的项目框架类的项目。前端项目名叫WebIteration,作用和后端的差不多。由于这两个项目不便透露,我尽量描述的详细一点。

4、运行index.js

node index.js

这样SocketIO的服务端就运行在3000端口上了。

 

二、创建后端发送推送接口

1、创建一个发送推送内容的Service

@Slf4j
@Service
@Transactional
public class SocketIoSendService {
    private static final String SERVER_NAME = "ServerIteration";

    public MessageModel execute(SocketIoForm model) {
        MessageModel messageModel = new MessageModel();
        Integer sendType = model.getSendType();
        String content = model.getContent();
        Long userId = model.getUserId();

        if (sendType == null) {
            return messageModel.setFail("请选择发送类型");
        }

        if (StringUtils.isBlank(content)) {
            return messageModel.setFail("请输入发送内容");
        }

        if (sendType == S_SocketIoSendType.POINT) {
            if (userId == null) {
                return messageModel.setFail("发送给指定用户,请输入用户ID");
            }
        }

        try {
            Socket socket = IO.socket("http://127.0.0.1:3000"); // INFO: Dechert: 2020/8/13 连接到SocketIO服务器
            socket.connect();
            AdvanceHashMap advanceHashMap = new AdvanceHashMap();
            advanceHashMap.put("content", content);
            if (sendType == S_SocketIoSendType.POINT) {
                advanceHashMap.put("userId", model.getUserId());
                socket.emit(SERVER_NAME + "PointSend", JSON.toJSONString(advanceHashMap));
            } else {
                socket.emit(SERVER_NAME + "BroadcastSend", JSON.toJSONString(advanceHashMap));
            }
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }

        messageModel.setSuccess();
        return messageModel;
    }
}

2、创建接口Controller

@Slf4j
@RestController
public class SaSocketIoSendController {
    @Autowired
    private SocketIoSendService service;

    @RequestMapping(value = "/saSocketIoSend.sahtml", produces = "application/json;charset=UTF-8", method = {RequestMethod.GET, RequestMethod.POST})
    public MessageModel execute(@RequestBody SocketIoForm model, HttpServletRequest request) {
        MessageModel messageModel = service.execute(model);
        return messageModel;
    }
}

其中MessageModel和AdvanceHashMap都是继承自HashMap的,只是对于返回数据的简单封装罢了

三、创建Vue前端

使用vue-cli创建一个Vue项目,这点我不再赘述了,网上例子多得是

其中main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import ElementUi from "element-ui"
import VueSocketIo from 'vue-socket.io';

Vue.config.productionTip = false
Vue.use(ElementUi)
Vue.use(new VueSocketIo({
  debug:true,
  connection:'127.0.0.1:3000'
}))

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

SocketIo.vue

<template>
  <div>
    <h1 @click="enterHello">SocketIO</h1>
    <h3>指定人员接收到的消息为:</h3>
    <div>{{receivePointMessage}}</div>
    <h3>广播消息为:</h3>
    <div>{{receiveBroadcastMessage}}</div>
  </div>
</template>

<script>
export default {
  name: "SocketIo",
  data() {
    return {
      receivePointMessage: "",
      receiveBroadcastMessage: "",
      userId: Math.ceil(Math.random() * 100)
    }
  },
  watch: {},
  mounted() {
    console.log('userId is ' + this.userId)
    // INFO: Dechert: 2020/8/13 订阅指定的和广播消息推送接口 
    this.sockets.subscribe(`WebIterationPointReceive_${this.userId}`, (data) => {
      this.receivePointMessage = data
    })

    this.sockets.subscribe(`WebIterationBroadcastReceive`, (data) => {
      this.receiveBroadcastMessage = data
    })
  },
  methods: {
    enterHello() {
      this.$router.push({
        path: "/hello"
      })
    },
  },
  sockets: {
    connect() {
      console.log('socket io is connected!!')
    },
  },
  beforeDestroy() {
    // INFO: Dechert: 2020/8/13 销毁订阅
    this.sockets.unsubscribe(`WebIterationReceive_${this.userId}`)
    this.sockets.unsubscribe(`WebIterationBroadcastReceive`)
  }
}
</script>

<style scoped>

</style>

四、测试效果

想要测试效果,请使用Postman,采用POST请求,内容类型为json,浏览器中复制几个同样的页面。指定人员发送时,userId由于是随机的,请在F12的console中找到userId。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个基于 Spring Boot、WebSocketVue 实现后端实时前端推送数据的代码示例: 1. 后端代码 ``` @Controller public class WebSocketController { private final WebSocketService webSocketService; @Autowired public WebSocketController(WebSocketService webSocketService) { this.webSocketService = webSocketService; } @GetMapping("/") public String index() { return "index"; } @Scheduled(fixedDelay = 1000) public void pushData() { webSocketService.sendAll(String.valueOf(System.currentTimeMillis())); } @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } } ``` ``` @Service public class WebSocketService { private final List<Session> sessions = new CopyOnWriteArrayList<>(); public void add(Session session) { sessions.add(session); } public void remove(Session session) { sessions.remove(session); } public void sendAll(String message) { sessions.forEach(session -> { try { session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } }); } } ``` 2. 前端代码 ``` <template> <div> <h1>Real-time data:</h1> <ul> <li v-for="(data, index) in dataList" :key="index">{{ data }}</li> </ul> </div> </template> <script> export default { data() { return { dataList: [] } }, mounted() { const ws = new WebSocket('ws://localhost:8080/ws'); ws.onmessage = (event) => { this.dataList.push(event.data); }; ws.onclose = () => { console.log('Connection closed'); }; } } </script> ``` 在这个示例中,我们在后端创建了一个定时任务,每秒钟向所有连接上的客户端推送当前时间戳。我们还创建了一个 WebSocketService,用于管理客户端连接和消息发送。 在前端,我们通过 Vue 的 mounted 生命周期创建了一个 WebSocket 连接,并在每次接收到服务器发来的消息时将其添加到一个数据列表中,然后在模板中通过 v-for 渲染出来。 要注意的是,我们在前端中只创建了一个 WebSocket 连接,用于接收服务器推送的数据。这是因为 WebSocket 是全双工通信,可以同时进行发送和接收操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值