解决内网拉取企微会话存档代理问题的一种办法

问题:客户的服务都是内网的,不能直接访问外网;访问外网的话需要走kong网关才能出去。

会话存档官网说可以使用socket5http方式拉取会话存档;我这边尝试了直接使用kong网关的ip和端口配置进去,是访问不了的

我后面就又尝试了使用nginxsquid 做正向代理的方式使用http方式访问,也是没有成功;这两种做代理服务器为什么不能成功,没有理解;有知道的朋友可以告诉我一下,有成功使用这两个做代理服务器拉取消息成功的朋友可以分享下经验。

搞一个socket5的代理服务器是可以成功,我没有试过,但是问过踩过坑的人说这种方式可行。

如果懒得麻烦再搭一个代理服务器,那就可以自己动手写一个简单的代理服务器搞定它。

大概的交互流程如下:

下面是全部的代码,拷过去,调一调应该就能用了

ForwardProxyApplication

java 复制代码
import xxx.ProxyService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.annotation.Resource;

@SpringBootApplication
public class ForwardProxyApplication implements CommandLineRunner {

    @Resource
    private ProxyService proxyService;

    public static void main(String[] args) {
        SpringApplication.run(ForwardProxyApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        proxyService.start(args);
    }
}

ProxyConfig

java 复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ProxyConfig {

    @Value("${socket.port}")
    public Integer socketPort;

    @Value("${proxy.host}")
    public String proxyHost;

    @Value("${proxy.port}")
    public Integer proxyPort;
}

ProxyService

java 复制代码
import xxx.config.ProxyConfig;
import xxx.thread.ProxyHandleThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

@Service
public class ProxyService {

    private static final Logger logger = LoggerFactory.getLogger(ProxyService.class);

    @Resource
    private ProxyConfig proxyConfig;

    public void start(String[] args) {
        ServerSocket ss = null;
        try {
            ss = new ServerSocket(proxyConfig.socketPort);
            logger.info("Server running at http://0.0.0.0:{}", proxyConfig.socketPort);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        while (true) {
            try {
                assert ss != null;
                Socket socket = ss.accept();
                socket.setSoTimeout(1000 * 60);
                String line = "";
                InputStream is = socket.getInputStream();
                String tempHost = "", host;
                int port = 80;
                String type = null;
                OutputStream os = socket.getOutputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(is));

                int temp = 1;
                StringBuilder sb = new StringBuilder();
                while ((line = br.readLine()) != null) {
                    logger.info(line + "-----------------");
                    if (temp == 1) {  
                        type = line.split(" ")[0];
                        if (type == null) continue;
                    }
                    temp++;
                    String[] s1 = line.split(": ");
                    if (line.isEmpty()) {
                        break;
                    }
                    for (int i = 0; i < s1.length; i++) {
                        if (s1[i].equalsIgnoreCase("host")) {
                            tempHost = s1[i + 1];
                        }
                    }
                    sb.append(line).append("\r\n");
                    line = null;
                }
                sb.append("\r\n"); 
                if (tempHost.split(":").length > 1) {
                    port = Integer.parseInt(tempHost.split(":")[1]);
                }
                host = tempHost.split(":")[0];
                Socket proxySocket = null;
                if (host != null && !host.equals("")) {
                	// todo 这里最重要的
                    host = proxyConfig.proxyHost;
                    port = proxyConfig.proxyPort;
                    proxySocket = new Socket(host, port);
                    proxySocket.setSoTimeout(1000 * 60);
                    OutputStream proxyOs = proxySocket.getOutputStream();
                    InputStream proxyIs = proxySocket.getInputStream();
                    if (Objects.requireNonNull(type).equalsIgnoreCase("connect")) {  
                        os.write("HTTP/1.1 200 Connection Established\r\n\r\n".getBytes());
                        os.flush();
                    } else {
                        proxyOs.write(sb.toString().getBytes(StandardCharsets.UTF_8));
                        proxyOs.flush();
                    }
                    new ProxyHandleThread(is, proxyOs).start(); //监听客户端传来消息并转发给服务器
                    new ProxyHandleThread(proxyIs, os).start(); //监听服务器传来消息并转发给客户端
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

ProxyHandleThread

java 复制代码
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketTimeoutException;

public class ProxyHandleThread extends Thread {
    private final InputStream input;
    private final OutputStream output;

    public ProxyHandleThread(InputStream input, OutputStream output) {
        this.input = input;
        this.output = output;
    }

    @Override
    public void run() {
        try {
            BufferedInputStream bis = new BufferedInputStream(input);
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length = bis.read(buffer)) != -1) {
                output.write(buffer, 0, length);
                length = -1;
            }
            output.flush();
            try {
                Thread.sleep(5000);     //不能执行完了,就把线程关掉,不然双方交互的数据还没有处理完,这里写了个睡眠 5s,可以酌情考虑
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (SocketTimeoutException e) {
            try {
                input.close();
                output.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                input.close();
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

没有搞定的,可以加好友一起聊聊,请备注csdn加我的

感谢 https://blog.csdn.net/jumprn/article/details/90173852

相关推荐
马剑威(威哥爱编程)6 天前
Java如何实现企业微信审批流程
java·开发语言·企业微信
假装我不帅6 天前
spreadjs实现类似于企业微信的协同提示
前端·javascript·企业微信·协同·spreadjs
LinDon_10 天前
【企业微信新版sdk】
企业微信
说私域12 天前
基于企业微信与开源 AI 智能名片 2 + 1 链动模式 S2B2C 商城小程序的客户运营模型优化研究
人工智能·开源·企业微信
奇怪的点13 天前
ubuntu 安装 企业微信
linux·ubuntu·企业微信
晚睡要秃头15 天前
通过微信小程序实现对接企业微信客服
javascript·微信小程序·vue·企业微信·uniapp
浮尘笔记21 天前
Go语言Gin框架调用企业微信接口根据手机号获取userid
golang·企业微信·gin
appearappear1 个月前
企业微信审批-回调,开发测试环境共用一个回调
企业微信
一如既往の2 个月前
【企业微信】群机器人自动消息配置
数据库·机器人·企业微信
bjshinegood2 个月前
企业微信AI社群助手:赋能企业私域运营的新引擎
人工智能·企业微信