局域网内聊天室(网页版)

GPT-oss:20b

GPT-oss:20b

图文对话
Gpt-oss

GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

由于自己平时工作学习的时候需要在各个平台之间传一些文本,但是又不想登录微信或者QQ这类软件,麻烦不说,有的时候其他人的电脑或平板上还没登陆,传给他们百度网盘链接或者其他的长文本就很麻烦,还有隐私问题,于是使用GPTCV大法,写了一个网页端的局域网聊天室,并打包成了docker镜像,使用方法放到最后。

这篇文章主要是想记录自己打包docker镜像并上传dockerhub的历程做个笔记。

首先,目录层级如下:
internal_chat/
├── app.py # Flask 主程序
├── Dockerfile # Docker 构建文件
├── requirements.txt # Python 依赖包
├── chat_log.json # 聊天记录文件(自动生成或初始化为空列表)
├── templates/
│ └── index.html # 网页聊天界面 HTML 模板
├── static/
│ ├──style.css # 可选:自定义样式
└──

直接上代码:
app.py

from flask import Flask, render_template, request, jsonify
from datetime import datetime, timedelta
import json
import os

app = Flask(__name__)
LOG_FILE = 'chat_log.json'
messages = []

def load_messages():
    global messages
    if os.path.exists(LOG_FILE):
        with open(LOG_FILE, 'r', encoding='utf-8') as f:
            try:
                messages = json.load(f)
            except json.JSONDecodeError:
                messages = []

def save_messages():
    with open(LOG_FILE, 'w', encoding='utf-8') as f:
        json.dump(messages, f, ensure_ascii=False, indent=2)

def clean_old_messages():
    global messages
    now = datetime.now()
    messages[:] = [
        msg for msg in messages
        if now - datetime.strptime(msg['timestamp'], '%Y-%m-%d %H:%M:%S') < timedelta(days=1)
    ]
    save_messages()

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/send', methods=['POST'])
def send_message():
    data = request.get_json()
    username = data.get('username', '匿名')
    message = data.get('message', '')
    now = datetime.now()
    timestamp = now.strftime('%Y-%m-%d %H:%M:%S')
    messages.append({
        'username': username,
        'message': message,
        'timestamp': timestamp
    })
    clean_old_messages()
    save_messages()
    return jsonify(success=True)

@app.route('/messages')
def get_messages():
    clean_old_messages()
    for msg in messages:
        msg['time'] = datetime.strptime(msg['timestamp'], '%Y-%m-%d %H:%M:%S').strftime('%H:%M:%S')
    return jsonify(messages=messages)

if __name__ == '__main__':
    load_messages()
    clean_old_messages()
    app.run(host='0.0.0.0', port=15920, debug=True)

index.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>局域网聊天</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/static/style.css">
</head>
<body>
    <div class="container">
        <h2>局域网聊天室</h2>
        <div id="usernameDisplay"></div>
        <div id="chatbox"></div>
        <div class="input-area">
            <input type="text" id="msg" placeholder="输入消息..." autofocus>
            <button onclick="sendMessage()">发送</button>
        </div>
    </div>

    <script>
        // 生成随机用户名(5位)
        function generateUsername() {
            return Math.random().toString(36).substr(2, 5).toUpperCase();
        }

        const username = generateUsername();
        document.getElementById('usernameDisplay').textContent = `用户名:${username}`;

        function fetchMessages() {
            fetch('/messages')
                .then(res => res.json())
                .then(data => {
                    const chatbox = document.getElementById('chatbox');
                    chatbox.innerHTML = '';
                    data.messages.forEach(msg => {
                        const item = document.createElement('div');
                        item.className = 'message';
                        item.innerHTML = `<span class="time">[${msg.time}]</span> <strong>${msg.username}</strong>: ${msg.message}`;
                        chatbox.appendChild(item);
                    });
                    chatbox.scrollTop = chatbox.scrollHeight;
                });
        }

        function sendMessage() {
            const msgInput = document.getElementById('msg');
            const msg = msgInput.value.trim();
            if (!msg) return;
            fetch('/send', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({ username: username, message: msg })
            }).then(() => {
                msgInput.value = '';
                fetchMessages();
            });
        }

        // 回车发送消息
        document.getElementById('msg').addEventListener('keydown', function (e) {
            if (e.key === 'Enter') {
                sendMessage();
            }
        });

        setInterval(fetchMessages, 1000);
        window.onload = fetchMessages;
    </script>
</body>
</html>

style.css

body {
    font-family: -apple-system, BlinkMacSystemFont, sans-serif;
    margin: 0;
    padding: 0;
    background: #f2f2f2;
}

.container {
    max-width: 600px;
    margin: auto;
    padding: 20px;
}

h2 {
    text-align: center;
    color: #333;
}

#usernameDisplay {
    text-align: center;
    margin-bottom: 10px;
    font-weight: bold;
}

#chatbox {
    background: #fff;
    height: 400px;
    overflow-y: auto;
    border: 1px solid #ccc;
    padding: 10px;
    border-radius: 5px;
}

.message {
    margin: 5px 0;
    line-height: 1.4;
}

.message .time {
    color: #888;
    margin-right: 5px;
}

.input-area {
    display: flex;
    margin-top: 10px;
}

#msg {
    flex: 1;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px 0 0 5px;
    font-size: 16px;
}

button {
    padding: 10px 15px;
    border: none;
    background: #007bff;
    color: white;
    font-size: 16px;
    cursor: pointer;
    border-radius: 0 5px 5px 0;
}

button:hover {
    background: #0056b3;
}

@media (max-width: 600px) {
    #chatbox {
        height: 300px;
    }
    button {
        font-size: 14px;
    }
    #msg {
        font-size: 14px;
    }
}

运行测试:
访问IP:15920
在这里插入图片描述

OK,运行正常,下一步我们打包成docker镜像

Linux执行命令:

docker login
[root@localhost internal_chat]# docker login

USING WEB-BASED LOGIN
To sign in with credentials on the command line, use 'docker login -u <username>'

Your one-time device confirmation code is: DKTP-BLDV
Press ENTER to open your browser or submit your device code here: https://login.docker.com/activate

Waiting for authentication in the browser¡­

访问网址:https://login.docker.com/activate
然后输入设备ID:DKTP-BLDV(在提示里面)
按照网页提示注册登录
登录后终端回显:

WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-stores

Login Succeeded

接下来Linux在项目目录下执行命令:

touch requirements.txt

里面只写一个模块

Flask==3.1.1

创建一个Dockerfile

touch Dockerfile

写入以下内容:

# Builder 阶段:安装依赖并安装python包
FROM python:3.11-alpine AS builder

WORKDIR /app

RUN apk add --no-cache gcc musl-dev libffi-dev

COPY requirements.txt .

RUN pip install --prefix=/install --no-cache-dir -r requirements.txt

COPY . .

# 运行阶段:只复制已安装的包和代码
FROM python:3.11-alpine

WORKDIR /app

# 复制 builder 阶段安装好的包
COPY --from=builder /install /usr/local

# 复制应用代码
COPY --from=builder /app /app

CMD ["python", "app.py"]

OK,执行打包命令:

docker build -t lan-chat .

注意最后有个 .

[root@localhost internal_chat]# docker build -t lan-chat .
[+] Building 20.0s (13/13) FINISHED                                                 docker:default
 => [internal] load build definition from Dockerfile                                          0.0s
 => => transferring dockerfile: 540B                                                          0.0s
 => [internal] load metadata for docker.io/library/python:3.11-alpine                         1.3s
 => [internal] load .dockerignore                                                             0.0s
 => => transferring context: 2B                                                               0.0s
 => [internal] load build context                                                             0.0s
 => => transferring context: 2.46kB                                                           0.0s
 => [builder 1/6] FROM docker.io/library/python:3.11-alpine@sha256:8068890a42d68ece5b62455ef  0.0s
 => CACHED [builder 2/6] WORKDIR /app                                                         0.0s
 => CACHED [builder 3/6] RUN apk add --no-cache gcc musl-dev libffi-dev                       0.0s
 => CACHED [builder 4/6] COPY requirements.txt .                                              0.0s
 => [builder 5/6] RUN pip install --prefix=/install --no-cache-dir -r requirements.txt       17.3s
 => [builder 6/6] COPY . .                                                                    0.2s 
 => [stage-1 3/4] COPY --from=builder /install /usr/local                                     0.2s 
 => [stage-1 4/4] COPY --from=builder /app /app                                               0.1s 
 => exporting to image                                                                        0.4s 
 => => exporting layers                                                                       0.4s 
 => => writing image sha256:7e1b8c7d6611d4d6b58cc739b91941dacfa2302689a136d74eaf31e0b3edd5fe  0.0s 
 => => naming to docker.io/library/lan-chat                                               0.0s

这里我选择python:3.11-alpine是为了压缩镜像体积

打包后我们查看一下:

[root@localhost internal_chat]# docker images
REPOSITORY                    TAG                  IMAGE ID       CREATED          SIZE
lan-chat                      latest               7e1b8c7d6611   32 seconds ago   64.4MB

好的,接下来我们打个tag

[root@localhost internal_chat]# docker tag lan-chat-app sspeaf/lan-chat:latest

然后push到dockerhub

[root@localhost internal_chat]# docker push sspeaf/lan-chat:latest
The push refers to repository [docker.io/sspeaf/lan-chat]
40f4d3da82c7: Pushed 
96b5e0494498: Pushed 
9a6a1c7594c7: Pushed 
ed1fa62b5e54: Mounted from library/python 
15b8ed2bc3f1: Mounted from library/python 
e980fad4908b: Mounted from library/python 
fd2758d7a50e: Mounted from library/python 
latest: digest: sha256:f536145b2b92468e6133e4b8b0964367d006501354a3368ba07461e2f5a3347d size: 1785

OK,我们执行下面的命令run一下试试:

docker run -d -p 15920:15920 --name lan-chat  --restart unless-stopped   -v /etc/localtime:/etc/localtime:ro   -v /etc/timezone:/etc/timezone:ro   sspeaf/lan-chat:latest

记得防火墙放开15920/tcp端口

浏览器访问下:
在这里插入图片描述
接下来在各个平台的浏览器内收藏IP:15920,然后添加到桌面就可以啦!

希望这个项目能帮到你

您可能感兴趣的与本文相关的镜像

GPT-oss:20b

GPT-oss:20b

图文对话
Gpt-oss

GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

因为太大,所以我压缩成7z格式了。 此课程设计包含三个主文件: ChatServer 聊天室服务端代码 Client 聊天室客户端代码 Bin 已编译程序 Web 聊天室浏览器端 配置如下: ①下载好Xampp并安装(http://sourceforge.net/projects/xampp/),然后将Web文件夹下的Chat文件夹里的内容复制到"Xampp安装目录\htdocs\Chat"目录下。 ②启动Xampp(包括Apache和MySql)。 ③打开http://服务器IP或者域名/PhpMyAdmin/并自行设置好连接用户名及密码。 ⑤新建数据库,库名为mfcchat。 ④进入mfcchat数据库点击“导入”,文件位置为Web目录下的MFCChat.sql。并点击执行以导入用户表。 ⑤打开Bin文件夹下的服务端文件夹,编辑ChatConf.ini文件,配置相应设置。 ⑥打开Client文件夹下的工程 1、编辑CClientDlg类下的InitChannel函数,编辑相应的频道信息。 2、编辑CClientDlg类下的OnInitDialog函数,找到ChannelListCtrl.SelectString(0, _T("风花雪月"));,改成默认频道名。 ⑦打开Client下Client文件夹,编辑ChatRoom.htm、Chatting.htm、RegisterDlg.htm,将里面所有IP地址替换成Xampp所在的主机的IP或者域名。 ⑧重新生成Client工程。 ⑨生成的客户端在Client\Client\Bin目录下,复制到"Bin\服务端"文件夹下即可。 最后打开"Bin\服务端"下的可执行文件即可开启聊天服务。然后把"Bin\客户端"分发出去即可使用。 注意:最新的版本由于加了监听实时在线功能,所以导致很多自己解决不了的BUG。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值