Skip to content

Commit 8d4fe46

Browse files
committed
generate session id in client side
to avoid duplicated session created in poor network environment
1 parent e00abda commit 8d4fe46

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

pywebio/platform/adaptor/http.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def request_obj(self):
3636
Return the current request object"""
3737
pass
3838

39-
def request_method(self):
39+
def request_method(self) -> str:
4040
"""返回当前请求的方法,大写
4141
Return the HTTP method of the current request, uppercase"""
4242
pass
@@ -46,12 +46,12 @@ def request_headers(self) -> Dict:
4646
Return the header dictionary of the current request"""
4747
pass
4848

49-
def request_url_parameter(self, name, default=None):
49+
def request_url_parameter(self, name, default=None) -> str:
5050
"""返回当前请求的URL参数
5151
Returns the value of the given URL parameter of the current request"""
5252
pass
5353

54-
def request_body(self):
54+
def request_body(self) -> bytes:
5555
"""返回当前请求的body数据
5656
Returns the data of the current request body
5757
@@ -93,7 +93,7 @@ def get_response(self):
9393
Get the current response object"""
9494
pass
9595

96-
def get_client_ip(self):
96+
def get_client_ip(self) -> str:
9797
"""获取用户的ip
9898
Get the user's ip"""
9999
pass
@@ -115,7 +115,7 @@ def __init__(self, session: Session, message_window: int = 4):
115115
def close_message(ack):
116116
return dict(
117117
commands=[[dict(command='close_session')]],
118-
seq=ack+1
118+
seq=ack + 1
119119
)
120120

121121
def get_response(self, ack=0):
@@ -266,15 +266,17 @@ def handle_request_context(self, context: HttpContext):
266266
return context.get_response()
267267

268268
ack = int(context.request_url_parameter('ack', 0))
269-
webio_session_id = None
270-
# 初始请求,创建新 Session
271-
if not request_headers['webio-session-id'] or request_headers['webio-session-id'] == 'NEW':
269+
webio_session_id = request_headers['webio-session-id']
270+
new_request = False
271+
if webio_session_id.startswith('NEW-'):
272+
new_request = True
273+
webio_session_id = webio_session_id[4:]
274+
275+
if new_request and webio_session_id not in cls._webio_sessions: # 初始请求,创建新 Session
272276
if context.request_method() == 'POST': # 不能在POST请求中创建Session,防止CSRF攻击
273277
context.set_status(403)
274278
return context.get_response()
275279

276-
webio_session_id = random_str(24)
277-
context.set_header('webio-session-id', webio_session_id)
278280
session_info = get_session_info_from_headers(context.request_headers())
279281
session_info['user_ip'] = context.get_client_ip()
280282
session_info['request'] = context.request_obj()
@@ -290,13 +292,15 @@ def handle_request_context(self, context: HttpContext):
290292
webio_session = session_cls(application, session_info=session_info)
291293
cls._webio_sessions[webio_session_id] = webio_session
292294
cls._webio_transports[webio_session_id] = ReliableTransport(webio_session)
293-
yield type(self).WAIT_MS_ON_POST / 1000.0 # <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <---
294-
elif request_headers['webio-session-id'] not in cls._webio_sessions: # WebIOSession deleted
295+
yield cls.WAIT_MS_ON_POST / 1000.0 # <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <--- <---
296+
elif webio_session_id not in cls._webio_sessions: # WebIOSession deleted
295297
close_msg = ReliableTransport.close_message(ack)
296298
context.set_content(close_msg, json_type=True)
297299
return context.get_response()
298300
else:
299-
webio_session_id = request_headers['webio-session-id']
301+
# in this case, the request_headers['webio-session-id'] may also startswith NEW,
302+
# this is because the response for the previous new session request has not been received by the client,
303+
# and the client has sent a new request with the same session id.
300304
webio_session = cls._webio_sessions[webio_session_id]
301305

302306
if context.request_method() == 'POST': # client push event

webiojs/src/session.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {error_alert} from "./utils";
1+
import {error_alert, randomid} from "./utils";
22
import {state} from "./state";
33
import {t} from "./i18n";
44

@@ -178,7 +178,7 @@ export class WebSocketSession implements Session {
178178

179179
export class HttpSession implements Session {
180180
interval_pull_id: number = null;
181-
webio_session_id: string = 'NEW';
181+
webio_session_id: string = '';
182182
debug = false;
183183

184184
private _executed_command_msg_id = -1;
@@ -209,6 +209,7 @@ export class HttpSession implements Session {
209209

210210
start_session(debug: boolean = false): void {
211211
this.debug = debug;
212+
this.webio_session_id = "NEW-" + randomid(24);
212213
this.pull();
213214
this.interval_pull_id = setInterval(() => {
214215
this.pull()
@@ -223,9 +224,13 @@ export class HttpSession implements Session {
223224
contentType: "application/json; charset=utf-8",
224225
dataType: "json",
225226
headers: {"webio-session-id": this.webio_session_id},
226-
success: function (data: { commands: Command[][], seq: number }, textStatus: string, jqXHR: JQuery.jqXHR) {
227+
success: function (data: { commands: Command[][], seq: number, event: number },
228+
textStatus: string, jqXHR: JQuery.jqXHR) {
227229
safe_poprun_callbacks(that._session_create_callbacks, 'session_create_callback');
228230
that._on_request_success(data, textStatus, jqXHR);
231+
if(that.webio_session_id.startsWith("NEW-")){
232+
that.webio_session_id = that.webio_session_id.substring(4);
233+
}
229234
},
230235
error: function () {
231236
console.error('Http pulling failed');

0 commit comments

Comments
 (0)