Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 更新包含flask socketio中消息列表的my dict时出现线程错误异常_Javascript_Python_Flask_Cs50_Flask Socketio - Fatal编程技术网

Javascript 更新包含flask socketio中消息列表的my dict时出现线程错误异常

Javascript 更新包含flask socketio中消息列表的my dict时出现线程错误异常,javascript,python,flask,cs50,flask-socketio,Javascript,Python,Flask,Cs50,Flask Socketio,我正在为cs50项目2构建一个基本的聊天应用程序 我有一个dict,它存储了我所有的消息,包括用户名、时间和消息,消息内容的值都在一个列表中 现在我正在使用会话将每条消息存储在自己的频道中,但当我将消息发布到聊天室时,我会得到回溯 Exception in thread Thread-5: Traceback (most recent call last): File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3

我正在为cs50项目2构建一个基本的聊天应用程序

我有一个dict,它存储了我所有的消息,包括用户名、时间和消息,消息内容的值都在一个列表中

现在我正在使用会话将每条消息存储在自己的频道中,但当我将消息发布到聊天室时,我会得到回溯

Exception in thread Thread-5:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/socketio/server.py", line 682, in _handle_event_internal
    r = server._trigger_event(data[0], namespace, sid, *data[1:])
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/socketio/server.py", line 711, in _trigger_event
    return self.handlers[namespace][event](*args)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/flask_socketio/__init__.py", line 282, in _handler
    return self._handle_event(handler, message, namespace, sid,
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/flask_socketio/__init__.py", line 713, in _handle_event
    ret = handler(*args)
  File "/Users/aparep7474/Desktop/project2/application.py", line 103, in post
    if len(messages_created[session['current_channel']]) > 100:
KeyError: 'Hello'
当用户单击post按钮时,它获取输入字段的值,然后通过submit post函数发出一条消息。然后,我的flask应用程序将接收到该消息,并将该信息附加到dict中,并向用户发出动态显示的消息

我的烧瓶代码:

大部分重要的代码都在末尾

import os, requests

from flask import Flask, session, redirect, render_template, request, jsonify
from flask_socketio import SocketIO, emit

from helpers import login_required

app = Flask(__name__)
app.config["SECRET_KEY"] = "4301"
socketio = SocketIO(app, async_mode='eventlet')

users_online = []

channels_created = []

messages_created = {}


@app.route("/")
@login_required
def index():

    if session.get("current_channel") is None:
        return redirect("/create_channel")

    else:
        return redirect("/channels/" + session.get("current_channel"))


@app.route("/log_in", methods=['GET','POST'])
def log_in():

    username = request.form.get("username")

    if request.method == "POST":

        if len(username) == 0:
            return render_template("error.html", message="username can't be empty.")

        if username in users_online:
            return render_template("error.html", message="that username already exists.")

        users_online.append(username)

        session['username'] = username

        session.permanent = True

        return redirect("/create_channel")

    else:
        return render_template("log_in.html")


@app.route("/log_out", methods=['GET','POST'])
def log_out():

    try:
        users_online.remove(session['username'])
    except ValueError:
        pass

    session.clear()

    return redirect("/")


@app.route("/create_channel", methods=['GET','POST'])
@login_required
def create_channel():

    session.pop("current_channel", None)

    new_channel = request.form.get("channel")

    if request.method == "POST":

        if new_channel in channels_created:
            return render_template("error.html", message="that channel already exists.")

        channels_created.append(new_channel)

        return redirect("/channels/" + new_channel)

    else:
        return render_template("create_channel.html", channels=channels_created)


@app.route("/channels/<channel>", methods=['GET','POST'])
@login_required
def channel_name(channel):

    session['current_channel'] = channel

    session.permanent = True

    return render_template("channel.html", channels=channels_created)


@socketio.on("submit post")
def post(data):

    if len(messages_created[session['current_channel']]) > 100:
        messages_created[session['current_channel']].pop(0)

    messages_created[session['current_channel']].append([session.get("username"), data["message"], datetime.now().strftime("%H:%M")])

    message = data["message"]

    time = datetime.now().strftime("%H:%M")

    emit("announce post", {"message": message, "time": time, "username": session.get("username")}, room=room, broadcast=True)


if __name__ == '__main__':
    socketio.run(app, debug=True)
导入操作系统、请求
从flask导入flask、会话、重定向、呈现模板、请求、jsonify
从flask_socketio导入socketio,发射
需要从帮助程序导入登录名
app=烧瓶(名称)
app.config[“密钥”]=“4301”
socketio=socketio(应用程序,async_mode='eventlet')
用户在线=[]
创建的频道=[]
消息\u已创建={}
@附件路线(“/”)
@需要登录
def index():
如果session.get(“当前_通道”)为无:
返回重定向(“/create\u channel”)
其他:
返回重定向(“/channels/”+session.get(“当前_通道”))
@app.route(“/log_in”,methods=['GET','POST']))
def登录():
用户名=request.form.get(“用户名”)
如果request.method==“POST”:
如果len(用户名)==0:
返回呈现模板(“error.html”,message=“用户名不能为空。”)
如果users\u online中的用户名为:
返回render_模板(“error.html”,message=“该用户名已存在。”)
用户\u online.append(用户名)
会话['username']=用户名
session.permanent=True
返回重定向(“/create\u channel”)
其他:
返回渲染模板(“log\u in.html”)
@app.route(“/log_out”,方法=['GET','POST']))
def log_out():
尝试:
用户在线。删除(会话['username'])
除值错误外:
通过
会话.清除()
返回重定向(“/”)
@app.route(“/create_channel”,方法=['GET','POST']))
@需要登录
def create_通道():
session.pop(“当前_频道”,无)
新建通道=request.form.get(“通道”)
如果request.method==“POST”:
如果在通道中创建了新的通道:
返回render_模板(“error.html”,message=“该通道已存在。”)
频道\u已创建。追加(新频道)
返回重定向(“/channels/”+新频道)
其他:
返回渲染模板(“create\u channel.html”,channels=channels\u created)
@app.route(“/channels/”,方法=['GET','POST'])
@需要登录
def通道名称(通道):
会话['current_channel']=频道
session.permanent=True
返回渲染模板(“channel.html”,channels=channels\u已创建)
@socketio.on(“提交帖子”)
def post(数据):
如果len(创建的消息[会话['current_channel']])>100:
已创建[会话['current\u channel']]的消息。pop(0)
消息\已创建[session['current\u channel']]。追加([session.get(“用户名”)、数据[“message”]、datetime.now().strftime(“%H:%M”))
消息=数据[“消息”]
time=datetime.now().strftime(“%H:%M”)
emit(“公布帖子”,{“消息”:消息,“时间”:时间,“用户名”:session.get(“用户名”)},room=room,broadcast=True)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
运行(app,debug=True)
我的HTML代码:

{% extends "layout.html" %}

{% block title %}
  {{ session.current_channel }}
{% endblock %}

{% block head %}
  <style>
    #box {
      box-sizing: border-box;
      border-radius: 5px;
      width: 100%;
      padding: 10px;
      border: 1px solid gray;
      margin: 0;
    }
  </style>
  <script src="{{url_for('static', filename='channel.js')}}"></script>
{% endblock %}

{% block content %}
  <h1 class="text-center">{{ session.current_channel }}</h1>
  <body>
    <div id="box">
      {% if messages_created %}
        {% for message in messages_created %}
          <ul>
            <li><strong> {{ message[0] }} </strong> : {{ message[1] }} <small class="float-right"> {{ message[2] }} </small></li>
          </ul>
          {% endfor %}
        {% endif %}
        <ul id="posts">
        </ul>
      </div>
    <hr>
    <form id="form">
      <input id="message" autofocus autocomplete="off" placeholder="Enter Your Post Here" style="height: 40px;width: 800px;" class="mt-3">
      <button id="button" class="btn btn-secondary">Post</button>
    </form>
  </body>
{% endblock %}
{%extends“layout.html”%}
{%block title%}
{{session.current_channel}
{%endblock%}
{%block head%}
#盒子{
框大小:边框框;
边界半径:5px;
宽度:100%;
填充:10px;
边框:1px纯色灰色;
保证金:0;
}
{%endblock%}
{%block content%}
{{session.current_channel}
{%if\u创建的邮件%}
{u创建的邮件中的邮件为%}
  • {{message[0]}:{{message[1]}{{message[2]}
{%endfor%} {%endif%}

邮递 {%endblock%}
html只包含一个导航栏,其中包含一个带有频道的下拉列表和一个注销按钮

最后,我的JS代码:

document.addEventListener('DOMContentLoaded', () => {

  var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);

  socket.on('connect', () => {
    document.querySelector('#form').onsubmit = () => {
      const message = document.querySelector('#message').value;
      socket.emit('submit post', {'message': message});
      document.querySelector("#message").value = '';
      return false;
    };
  });

  socket.on('announce post', data => {
    console.log('received');
    const li = document.createElement('li');
    li.innerHTML = `<strong> ${data.username} </strong> : ${data.message} <small class="float-right"> ${data.time} </small>`;
    document.querySelector('#posts').append(li);
  });
});
document.addEventListener('DOMContentLoaded',()=>{
var socket=io.connect(location.protocol+'/'+document.domain+':'+location.port);
socket.on('connect',()=>{
document.querySelector(“#form”).onsubmit=()=>{
const message=document.querySelector(“#message”).value;
emit('submitpost',{'message':message});
document.querySelector(“#message”)。值=”;
返回false;
};
});
socket.on('announcepost',data=>{
console.log('received');
const li=document.createElement('li');
li.innerHTML=`${data.username}:${data.message}${data.time}`;
document.querySelector(“#posts”).append(li);
});
});

更改当前频道时,您应该将创建的[会话['current\u channel']]消息初始化为空列表。如果使用会话创建空列表,如何初始化该列表?很抱歉,我对所有这些python列表都是新手,只需为会话中的当前频道条目分配一个空列表(即
[]
)。非常感谢您的帮助。当我创建新频道时,我也会从创建频道的位置创建一个列表。当您更改当前频道时,您应该将创建的[会话['current\u channel']]]消息初始化为空列表。如果使用会话创建空列表,我如何初始化它?很抱歉,我对所有这些python列表都是新手,只需为会话中的当前频道条目分配一个空列表(即
[]
)。非常感谢您的帮助。当我创建新频道时,我还创建了一个列表,从中可以看到频道的位置