websocket.html 7.6 KB
<!DOCTYPE html>
<html lang="en">
<link href="css/markdown.css" rel="stylesheet" type="text/css"/>

<head>
    <meta charset="UTF-8">
    <title>战损版ChatGPT-WebSocket实现流式输出</title>
    <link rel="icon" type="image/png" sizes="32x32" href="image/favicon-32x32.png">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="js/markdown.min.js"></script>


    <script>
        function setText(text, uuid_str) {
            let content = document.getElementById(uuid_str)
            content.innerHTML = marked(text);
        }

        function uuid() {
            var s = [];
            var hexDigits = "0123456789abcdef";
            for (var i = 0; i < 36; i++) {
                s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
            }
            s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
            s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
            s[8] = s[13] = s[18] = s[23] = "-";

            var uuid = s.join("");
            return uuid;
        }


        window.onload = function () {
            var socket
            let uuid_str = '';
            let text = '';
            let disconnectBtn = document.getElementById("disconnectSSE");
            let messageElement = document.getElementById("message");
            let chat = document.getElementById("chat");
            let uid = window.localStorage.getItem("uid");
            if (uid == null || uid == '' || uid == 'null') {
                uid = uuid();
            }
            // 设置本地存储
            window.localStorage.setItem("uid", uid);
            if (typeof (WebSocket) == "undefined") {
                console.log("您的浏览器不支持WebSocket");
            } else {
                console.log("您的浏览器支持WebSocket");
                //实现化WebSocket对象
                //指定要连接的服务器地址与端口建立连接
                //注意ws、wss使用不同的端口。我使用自签名的证书测试,
                //无法使用wss,浏览器打开WebSocket时报错
                //ws对应http、wss对应https。
                socket = new WebSocket("ws://localhost:8000/websocket/"+uid);
                //连接打开事件
                socket.onopen = function () {
                    console.log("Socket 已打开");
                };
                //收到消息事件
                socket.onmessage = function (msg) {
                    if (msg.data == "[DONE]") {
                        text = '';
                        return;
                    }
                    let json_data = JSON.parse(msg.data)
                    if (json_data.content == null || json_data.content == 'null') {
                        text = '';
                        return;
                    }
                    text = text + json_data.content;
                    setText(text, uuid_str)
                };
                //连接关闭事件
                socket.onclose = function () {
                    console.log("Socket已关闭");
                };
                //发生了错误事件
                socket.onerror = function () {
                    alert("服务异常请重试并联系开发者!")
                }
                //窗口关闭时,关闭连接
                window.unload = function () {
                    socket.close();
                };
            }
            // 回车事件
            messageElement.onkeydown = function () {
                if (window.event.keyCode === 13) {
                    if (!messageElement.value) {
                        return;
                    }
                    uuid_str = uuid();
                    socket.send(messageElement.value);
                    //新增问题框
                    chat.innerHTML += '<tr><td style="height: 50px;">' + messageElement.value + '</td></tr>';
                    messageElement.value = null
                    //新增答案框
                    chat.innerHTML += '<tr><td><article id="' + uuid_str + '" class="markdown-body"></article></td></tr>';
                }
            };

            disconnectBtn.onclick = function () {
                if (socket) {
                    socket.close();
                }
            };

        };
    </script>
</head>

<body>
<!--<div class="float-card-item send-btn">-->
<!--    <a id="connectSSE" rel="noopener noreferrer">发送请求</a>-->
<!--</div>-->
<!--<div class="float-card-item dis-btn">-->
<!--    <a id="disconnectSSE" rel="noopener noreferrer">断开连接</a>-->
<!--</div>-->
<div class="float-card">
    <div class="float-card-item">
        <a href="https://www.unfbx.com" target="_blank" rel="noopener noreferrer">Website</a>
    </div>
    <div class="float-card-item">
        <a href="https://github.com/Grt1228" target="_blank" rel="noopener noreferrer">Github</a>
    </div>
    <div class="float-card-item">
        <a id="disconnectSSE" rel="noopener noreferrer">停止输出</a>
    </div>
</div>
<div class="input-card">
    <div class="input-card-item">
        <input id="message" placeholder="输入你的问题,回车结束......" type="text">
    </div>
</div>
<div class="container">
    <table border="1">
        <tbody id="chat">
        <tr>
            <td>
                <pre style="font-size: 15px">
                    帮忙点个star吧<br/>
                    1、依赖ChatGPT开源Java SDK:<a rel="noopener noreferrer" href="https://github.com/Grt1228/chatgpt-java"
                                             target="_blank" style="font-size: 15px">https://github.com/Grt1228/chatgpt-java</a><br/>
                    2、本项目免费开源地址:<a rel="noopener noreferrer" href="https://github.com/Grt1228/chatgpt-steam-output"
                                   target="_blank" style="font-size: 15px">https://github.com/Grt1228/chatgpt-steam-output</a><br/>
                    3、默认保持连接5分钟,默认上下文保持10个,5分钟无请求上下文会话销毁。
                </pre>
            </td>
        </tr>
        </tbody>
    </table>
</div>


</body>
<style>
    .markdown-body {
        box-sizing: border-box;
        min-width: 200px;
        max-width: 980px;
        margin: 0 auto;
        padding: 45px;
    }

    @media (max-width: 767px) {
        .markdown-body {
            padding: 15px;
        }
    }

    input {
        height: 50px;
        width: 500px;
        font-size: 20px;
        background: url(10) no-repeat;
        color: #d0838e;
    }

    .container {
        width: 980px;
        border: 1px solid black;
        display: flex;
        flex-direction: column;
        margin-left: 150px;
        margin-top: 40px;
    }

    .input-card {
        position: fixed;
        display: inline-block;
        right: 37%;
        top: 80%;
    }

    .input-card-item {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        margin-bottom: 16px;
    }

    .float-card {
        position: fixed;
        display: inline-block;
        right: 120px;
        top: 100px;
    }

    .float-card-item {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        width: 60px;
        height: 60px;
        border-radius: 50%;
        background-color: #ccccd6;
        margin-bottom: 16px;
    }

    .float-card-item:last-child {
        margin-bottom: 0px;
        background-color: #d0838e;
    }

    .float-card-item a {
        text-decoration: none;
        color: #594649;
        font-size: 13px;
    }
</style>
</html>