[英]Unexpected behavior when using websockets
我想創建一個基本的聊天系統,允許用戶將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
該消息給所有的正在偵聽該socket
clients
。 但它不是那樣工作的。 有時會,有時不會。
我可以確認的一件事是,消息 100% 的時間都保存到數據庫和文件系統中。 我也總是從HTTP request
得到響應,但是當我從client
emit
event
並在服務器中print
消息時,有時我會得到None
或之前的消息記錄到控制台。
因此,當該消息發送到client
,我的“ error catching block
”將看到它undefined
或已存在,因此它將return
而不添加它(因為它當然不應該添加它)。
有沒有人遇到過這個問題? 我對某事有錯誤的看法嗎? 還是我的代碼有問題?
我想到了。
經過一段時間分析我的代碼后,我注意到我沒有在同一個transaction
execute
以下兩個queries
:
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
高級抽象,它具有非常松散的事務管理系統(自動打開/關閉)。 所以我不得不隱含地告訴它在執行兩個查詢之前不要關閉事務。
結果,我總是得到最新的插入,而不是事先發生的插入(就像我更新代碼之前的情況一樣)。
向您展示,如果您沒有提前考慮所有用例,代碼抽象並不總是一個好主意。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.