我想创建一个基本的聊天系统,允许用户将file
附加到给定的消息上。
web sockets
存在问题,因为通过它们发送file
非常困难。除非您要将其转换为二进制数据。但是,这对我不起作用,因为我希望能够与服务器上的文件进行交互,并且由于我具有多种文件类型(不同的图像,视频和Gif图像),所以我不能只解码二进制文件。
这是我的代码:
我在request
上上传邮件的位置:
// this.state._new_message : {
// _message_type_id:int,
// _message:string || file,
// _user_id:int,
// _conversation_id:int
// } -> this is what a _new_message object looks like.
let fd = new FormData()
if(this.state._new_message._message_type_id !== 1){
fd.append("file", this.state._new_message._message)
}
fd.append("message", JSON.stringify(this.state._new_message))
Axios.post(API_URL+"/api/chat/send_message", fd)
.then(res => res.data)
.then(res => {
this.socket.emit("message", res._message)
})
我处理request
的地方:
def send_message(self, request):
data = request.form["message"]
data = json.loads(data)
if data["_message_type_id"] != 1:
data["_message"] = "Loading Message. Please Wait."
query = fdb.prepare(data, "_messages") # Converts the data dict to a query string
fdb.create(query["query_string"], query["query_params"]) # Interacts with Database
_message = fdb.read("""SELECT * FROM _messages WHERE _id = LAST_INSERT_ID()""", (), False)
if data["_message_type_id"] != 1:
file = request.files["file"]
# OpenCV magic... #
path = "path/to/file"
file.save(path)
fdb.update("""UPDATE _messages SET _message = %s WHERE _id = %s""", (url_path, _message["_id"])) # Interacts with Database
url_path = "url/path/to/file"
_message["_message"] = url_path # If message is not text, set it to be the path to the file instead
return jsonify({
"_message" : _message
})
这是我收听event
(server
)的地方:
@socket.on("message")
def handleMessage(msg):
print(msg)
send(msg, broadcast=True)
return None
这是我收听event
(client
)的地方:
this.socket.on("message", data => {
if(data == null || data._message_type_id == undefined) return
if(this.props.chat.messages.messages !== null)
if(this.props.chat.messages.messages.filter(message => parseInt(message._id) === parseInt(data._id)).length > 0) return
this.props.addMessage(data)
})
根据该代码,您希望通过HTTP
发送一条消息,该消息将通过HTTP
处理并发送回去,然后将响应发送到server
通过socket
和socket
,然后将该send
消息发送给所有正在监听该clients
的{{1}}。但这不是那样的。有时候会,有时候却没有。
我可以确认的一件事是,消息会100%地保存到数据库和文件系统中。我也总是收到socket
的响应,但是当我在服务器中从HTTP request
和emit
收到event
client
消息时,我有时得到print
或上一条消息记录到控制台。
因此,当该消息发送到None
时,我的“ client
”将看到其error catching block
或已经存在,因此它将undefined
而不添加它(因为它当然不应该添加)。
有人曾经遇到过这个问题吗?我对某事有错误的主意吗?还是我的代码有问题?
答案 0 :(得分:0)
我知道了。
经过一段时间的分析,我发现我不在同一execute
中queries
后面的两个transaction
:
fdb.create(query["query_string"], query["query_params"]) # Interacts with Database
_message = fdb.read("""SELECT * FROM _messages WHERE _id = LAST_INSERT_ID()""", (), False)
我开发的fdb
扩展基本上是sqlalchemy
的高级抽象,它具有非常宽松的事务管理系统(自动打开/关闭)。因此,我不得不隐式告诉它在执行两个查询之前不要关闭事务。
结果,我总是得到最新的插入内容,而不是事先发生的插入内容(就像我更新代码之前的情况一样)。
向您展示,如果您不考虑所有高级用例,那么抽象代码并不总是一个好主意。