最近有個項目想把c/s的代碼轉(zhuǎn)成mvc的坑雅,這聽起來并不困難。
如果UI和業(yè)務(wù)邏輯良好分離了的話衬横,不會花太多的功夫裹粤,應(yīng)該多數(shù)的內(nèi)容都能重復(fù)利用。
但在實際的操作過程中冕香,發(fā)現(xiàn)業(yè)務(wù)邏輯代碼和UI提示全是混在一起的蛹尝,尤其里面有這樣的代碼很多:
public class MyLogic
{
public int DoPress(string bin)
{
if (string.IsNullOrEmpty(bin))
{
System.Windows.Forms.MessageBox.Show("數(shù)據(jù)為空,請登錄后使用");
return -1;
}
return 0;
}
}
這是一段偽代碼悉尾,不是真實的代碼內(nèi)容突那。這段代碼背后有這樣的信息:
- MyLogic類是底層的代碼,有很多系統(tǒng)都在調(diào)用它构眯,關(guān)系錯綜復(fù)雜
- 代碼內(nèi)需要有合法性的檢驗愕难,如果合法性校驗失敗,那函數(shù)會被return惫霸,錯誤信息需要讓用戶看到
現(xiàn)在的問題是猫缭,這個MessageBox.Show()的內(nèi)容我怎么才能顯示用戶這一端來呢?
首先壹店,b/s的程序猜丹,這些代碼是運(yùn)行在服務(wù)器端的,原來的MessageBox.Show()不會有任何的效果硅卢。
如果我們修改原先的函數(shù)簽名射窒,將 數(shù)據(jù)為空,請登錄后使用
這句話傳輸?shù)綖g覽器将塑,再用javascript的alert來提示脉顿。技術(shù)上是可以實現(xiàn)的。
就像這樣:
public class MyLogic
{
public Tuple<int, string> DoPress(string bin)
{
if (string.IsNullOrEmpty(bin))
{
//System.Windows.Forms.MessageBox.Show("數(shù)據(jù)為空点寥,請登錄后使用");
return new Tuple<int, string>(-1, "數(shù)據(jù)為空艾疟,請登錄后使用");
}
return new Tuple<int, string>(-1, null);
}
}
這個Tuple會被返回出去,最后傳輸?shù)綖g覽器敢辩。
然而蔽莱,這會修改原先的函數(shù)簽名,所有使用DoPress的函數(shù)都要修改戚长,并且盗冷,有的地方還是使用反射來調(diào)用的,要這樣修改历葛,會帶來巨大的工作量正塌,
根據(jù)這個具體的情況,我不得不去想如何在有限的時間內(nèi)來完成這件事恤溶。
問題的核心是:如何不修改函數(shù)的簽名乓诽,并將相關(guān)的信息輸出到瀏覽器?
我首先浮現(xiàn)了第一個解決方案是SSE(Server sent event)鸠天,它是HTML5里服務(wù)器向客戶端推送事件的一種方式稠集。很快我寫了一個小的demo來進(jìn)行測試饥瓷,確實可以用,但是有問題:非常的慢呢铆,Server產(chǎn)生了消息之后棺克,最長需要等待4秒才能看到提示消息。
我google了這個問題确买,也看到其他人的討論:https://stackoverflow.com/questions/12297740/server-sent-events-work-but-with-a-massive-time-delay
但最后這個問題還是沒有解決。
于是我轉(zhuǎn)向了SignalR湾趾,很快寫了另外的一個demo撑帖,這次工作良好澳眷,消息瞬時到達(dá)钳踊。
那么,之前的項目修改成什么樣子呢拓瞪?
public class MyLogic
{
public int DoPress(string bin)
{
if (string.IsNullOrEmpty(bin))
{
MessagePushHelper.PushSignalR("數(shù)據(jù)為空祭埂,請登錄后使用");
return -1;
}
return 0;
}
}
可以看到兵钮,之前的MessageBox.Show()改成了我自己寫的MessagePushHelper.PushSignalR()舌界,其他位置不變呻拌,這樣應(yīng)該是最小改動的解決方案了。
只不過有一點(diǎn)需要注意的是:要注意多個用戶同時使用時的情況(你不能對外廣播出錯消息)
最后靴拱,簡單的記錄一下步驟:
若要使用SSE
- 將輸出內(nèi)容標(biāo)記為 text/event-stream
- 輸出你想要的內(nèi)容
若要使用SignalR
- nuget包 install-package Microsoft.AspNet.SignalR
- 創(chuàng)建hub
- 創(chuàng)建startup類袜炕,打上OwinStartup標(biāo)記
- 在頁面引用 jquery.signalR-2.2.2.min.js和signalr/hubs
- 啟動hub并接收數(shù)據(jù)
文中提到的解決方案初家,可在github上查看:https://github.com/syler/Fun/tree/master/SSE-SignalR
我的博客地址:https://1few.com/SSE-SignalR