基于Socket协议通过RPC调用获取某音直播弹幕+注入js方法

首先是在直播间网页版f12打开开发者工具,找到wss也就是websocket栏,ctrl+f搜索关键字样new WebSocket,可以找到创建ws的位置,然后打开源文件位置

接下来就是写一段js将弹幕内容socket发送出去,需要先将此文件复写到本地,用挂载本地磁盘的文件复写来生效

window.dataLx = s.toObject();
                        !function() {
                            var res = window.dataLx;
                            if (window.flagLX) {
                                window.socket.emit("gaosuni", JSON.stringify(res));
                            } else {
                                var ws = window.io("ws://10.236.233.98:9999");
                                window.socket = ws;
                                window.flagLX = true;
                                ws.emit("gaosuni", JSON.stringify(res));
                            }
                        }();

这里使用socket.io库来实现,也可以直接用原生的socket

那么如何植入socket.io库呢,这里首先是尝试直接在页面上种植一个script标签来引入socket.io

https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.5.1/socket.io.js

尝试一:

尝试直接种植一个script标签,发现由于不安全跨站脚本,被拦截了,故失败
解决办法也就是不用跨站脚本,用本站的就行了,直接copy到这里

如果还是想引入脚本的话也有办法

办法1 通过chrome扩展程序引入js脚本

办法2 通过Fiddler抓包替换

首先在Fidder -> Rules -> Customize Rules里面  Go -> to OnBeforeReponse
加入如下代码,目的是每次页面自动引入js,这里引入抖音直播间下的js保证域名一致
if (oSession.oResponse.headers.ExistsAndContains("Content-Type","text/html")){
            if(oSession.HostnameIs("live.douyin.com")||oSession.uriContains("live.douyin.com")){
                oSession.utilDecodeResponse();
                oSession.utilReplaceInResponse('</body>','<script src="https://live.douyin.com/socket.io.js"></script></body>');
            }
        }

但是实际上live.douyin.com下并没有socket.io.js,于是我们抓请求然后替换成本地的socket.io.js文件就好了

如果报错:
was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint
将chrome设置允许加载不安全内容即可
如果报错:Access to XMLHttpRequest at 'http://10.236.233.98:9999/socket.io/?EIO=4&transport=polling&t=O5lvG57' from origin 'https://live.douyin.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

可以通过一个chrome插件来解决跨域

如果需要用安全协议使用 wss 类似 https
需要域名配了证书,以本地local.kong.com为例
host配置 10.236.233.98 local.kong.com

在10.236.233.98机器上启服务
申请本地测试证书详见 http://www.kongxiangbo.com/?p=3324
// server.js
const express = require('express');
const socketio = require('socket.io');
const fs = require('fs');
const http = require('http');
const https = require('https');
const app = express();

const Socket = require('./socket.js');

// const port = process.env.PORT || 9999;
// const server = http.createServer(app).listen(9999, () => {
//   console.log('Server Listening on port: ' + port)
// })

const httpsOption = {
    key : fs.readFileSync("./https/private.key"),
    cert: fs.readFileSync("./https/cert.pem")
}
const safePort = 443;
const server_safe = https.createServer(httpsOption, app).listen(safePort, () => {
	console.log('Server https on port: ' + safePort)
})

// 监听socket服务
// const io = socketio(server)
const io = socketio(server_safe)

const socket = new Socket(io);

// 监听连接进入游戏的回调
io.on('connect', item => {
  socket.listen(item)
})
// socket.js
class Socket{
  constructor(io){
    this.io = io;
  }

  listen(socket){
    console.log(`Player connected! Socket Id: ${socket.id}`)

    socket.on('gaosuni', this.gaosuni.bind(null, socket))
  }

  gaosuni = (socket, msg) => {
    console.log(msg)
  }
}

module.exports = Socket
!function() {
                            var res = window.dataLx;
                            if (window.flagLX) {
                                window.socket.emit("gaosuni", JSON.stringify(res));
                            } else {
                                var ws = window.io("wss://local.kong.com:443");
                                window.socket = ws;
                                window.flagLX = true;
                                ws.emit("gaosuni", JSON.stringify(res));
                            }
                        }();

如果报错:ERR:CERT_AUTHORITY_INVALID 就先在地址栏访问一次
https://local.kong.com
然后继续访问