学习glm大模型接口,websocket,sse,nginx代理

196 阅读3分钟

1.http基础

1.2.调用GLM-4

智谱AI开放平台 (aminer.cn)

按照文档创建访问

HttpUtil.createPost(url)
        .addHeaders(_headers_)
        .body(body.toString())
        .timeout(timeout)
        .execute();

image.png

HashMap<String, String> _headers_ = new HashMap<>();
_headers_.put("Content-Type", "application/json");
_headers_.put("Authorization","{id}.{key}");

image.png

使用hutool 中JSONObject创建请求体 ,JSONObject,JSONArray

JSONObject set(String key, Object value)

举例

构建第一个参数

JSONObject body = new JSONObject();
body.set("model", "glm-4"); // 设置模型名称

构建第二个参数

JSONArray messagesArray = new JSONArray(); // 创建消息数组
   messageObj.set("role", "user");
    messageObj.set("content", prompt);
    messagesArray.add(messageObj); // 添加消息到数组
body.set("messages", messagesArray); // 将消息数组添加到参数中

2.2 处理返回数据

返回HttpResponse

image.png

请求的stream参数确定响应体格式 Content-Type=[application/json; charset=UTF-8] Content-Type=[text/event-stream;charset=UTF-8]

响应内容通过HttpResponse.body(hutool工具)获取

同步数据处理

直接获取.body方法获取

流式响应体

当我们使用apifox客户端访问时

image.png 这时返回的流式响应块,经过尝试hutool的httputil无法实现,全部加载response后才能处理 但okhttp中的utils可以实现

image.png

image.png

再用这个回调方式请求,实现对流式响应块的处理


client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        e.printStackTrace();
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        try (ResponseBody responseBody = response.body();
             InputStream inputStream = responseBody.byteStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {

            String line;
            while ((line = reader.readLine()) != null) {
                // 处理每一行数据
                System.out.println(line);
            }
        }
    }
});

依次打印消息

image.png

这个数据可用于sse等等

2. 项目

简介

使用nginx+内网穿透让某个朋友访问,

  • 当没有ws连接时,就会ai回答
  • 当有ws连接时,就ws查看并且返回数据,实现人的模拟会话

使用的一些入门技术:sse,http,websockt,内网穿透

好玩的地方:可以建立websocket连接,当连接不为0时,就使用人工回复

回答的效果都是sse

首页:效果是sse,按照大模型的返回加载

image.png 当没有人登录时,就访问大模型(参考上个博客)

image.png

在一个界面建立websocket连接

image.png

这时我们尝试在ai界面发送问题,会传递到这个页面

image.png

image.png

"前端"页面就会收到这个消息

image.png

2.详细代码

前端 访问页面+后台处理会话的页面

<!DOCTYPE html>

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SSE Demo</title>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

</head>
<body>
<h1>SSE Demo</h1>

<div id="chatArea">
    <!-- 聊天内容将显示在这里 -->
</div>
<hr>
<div id="chat">
    <!-- 聊天内容将显示在这里 -->
</div>

    <input id="msg" placeholder="输入消息...">
    <button id="send" onclick="sendmsg()">发送</button>

<div id="output"></div>

<script>
    function sendmsg() {
        var msg = $("#msg").val();
        var url = "http://localhost:8081/ssemsg?msg=" + encodeURIComponent(msg);

        const eventSource = new EventSource(url);

        $("#chat").append("<p>"+msg+"<p>");
        $("#chat").append("<p>");
        eventSource.addEventListener('customMSG', function(event) {
            try {
               
                // 尝试解析接收到的JSON数据
                const data = JSON.parse(event.data);
                console.log('Received data:', data);

                // 处理数据,例如更新页面内容
                if (data.choices && data.choices.length > 0) {
                    const content = data.choices[0].delta.content;
                    $("#chat").append(content);
                }
            } catch (error) {
                // 处理解析错误
                console.error('Error parsing JSON:', error);
                eventSource.close();
            }
        });

        eventSource.onerror = function(error) {
            console.error('EventSource failed:', error);
         
            // 处理错误,例如显示错误消息或重试连接
        };


        $("#msg").val('');

    }

    function initSSE() {
      
       const eventSource = new EventSource("http://localhost:8081/sse");

        eventSource.addEventListener('customEvent', function(event) {
            try {

             

                // 尝试解析接收到的JSON数据
                const data = JSON.parse(event.data);
                console.log('Received data:', data);
                
                
                // 处理数据,例如更新页面内容
                if (data.choices && data.choices.length > 0) {


                    const content = data.choices[0].delta.content;
                  
                    $("#chatArea").append(content);
                }
            } catch (error) {
                // 处理解析错误
                console.error('Error parsing JSON:', error);
            }
        });

        eventSource.onerror = function(error) {
            console.error('EventSource failed:', error);
            eventSource.close();
            // 处理错误,例如显示错误消息或重试连接
        };
    }

    window.onload = initSSE;
</script>

</body>
</html>
<!DOCTYPE html>

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket Demo</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        #output {
            height: 10000px;
            overflow-y: scroll;
            margin-bottom: 20px;
        }
    </style>
</head>
<body>
    <h1>WebSocket Chat</h1>
    <input type="text" id="message" placeholder="Type your message here...">
    <button onclick="sendMessage()">Send</button>
    <hr>
    <button onclick="connect()">Connect</button>
    <button onclick="disconnect()">Disconnect</button>
    <button onclick="clearOutput()">Clear Output</button>
    <div id="output"></div>

    <script>
        var socket = new WebSocket('ws://127.0.0.1:8081/websocket/m/n/1');

        socket.onopen = function(event) {
            document.getElementById('output').innerHTML += '<p>Connected to the server</p>';
        };

        socket.onmessage = function(event) {
            document.getElementById('output').innerHTML += '<p>' + event.data + '</p>';
        };

        socket.onclose = function(event) {
            document.getElementById('output').innerHTML += '<p>Disconnected from the server</p>';
        };

        socket.onerror = function(error) {
            document.getElementById('output').innerHTML += '<p>Error: ' + error.message + '</p>';
        };

        function connect() {
            if(socket === null){
            socket = new WebSocket('ws://127.0.0.1:8081/websocket/m/n/1');

            socket.onopen = function(event) {
                document.getElementById('output').innerHTML += '<p>Connected to the server</p>';
            };

            socket.onmessage = function(event) {
                document.getElementById('output').innerHTML += '<p>' + event.data + '</p>';
            };

            socket.onclose = function(event) {
                document.getElementById('output').innerHTML += '<p>Disconnected from the server</p>';
            };

            socket.onerror = function(error) {
                document.getElementById('output').innerHTML += '<p>Error: ' + error.message + '</p>';
            };}
        }

        function sendMessage() {
            var input = document.getElementById('message');
            socket.send(input.value);
            input.value = '';
        }
           function disconnect() {
            if (socket !== null) {
                socket.close();
                socket = null;
                document.getElementById('output').innerHTML += '<p>方法关闭</p>';
            } else {
                document.getElementById('output').innerHTML += '<p>无连接</p>';
            }
        }

        function clearOutput() {
            document.getElementById('output').innerHTML = '';
        }
    </script>

</body>
</html>

**后端**

面向前端编程就行