在HTTP協議下使用JSON在flash和C# web程式之間通訊
先把文章中要用到一些擴充套件程式集貼出來。
C#用到了System.Web.Extensions程式集,包括3個檔案:
System.Web.Extensions.dll
System.Web.Extensions.Design.dll
AJAXExtensionsToolbox.dll
Flash用到了adobe的corelib-.90程式集:
corelib.swc
網上現在有很多將flash與C# web 服務程式通訊的資料,不過很多都是用remoting或者web service的方式做的,而且很多高手還做了效率比較,結果是基於TCP協議的remoting效率最好,但是這裡對remoting就不多說了,並且基於TCP的remoting因為協議不同效率差別肯定明顯。我還是介紹在HTTP協議下的通訊方法吧。
這裡使用iis作為伺服器,服務程式只要能處理客戶端提交的資料,能向客戶端返回資料就行(當然push做不到,http協議嘛)。所以處理程式大多直接實現IHttpHandle介面,當然從Page繼承是一點也沒有問題的,因為Page類也實現了IHttpHandle介面,如何繼承Page,如何實現IHttpHandle的介面方法就給個例子吧,這個資料挺多的。
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.SessionState;
namespace com.Flight.Script
{
/// <summary>
/// 指令碼控制請求,IRequiresSessionState介面沒有啥方法,純粹為了session支援
/// </summary>
public class ScriptHandler : IHttpHandler, IRequiresSessionState
{
/// <summary>
/// 處理指令碼請求
/// </summary>
/// <param name="context">指令碼名稱</param>
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Write("輸出內容");
}
/// <summary>
/// 是否允許後續請求處理
/// </summary>
public bool IsReusable
{
get
{
return true;
}
}
}
}
這裡提一下web.config配置,下面是一個例子,在這裡例子裡面我修改了副檔名“.do”,這樣的配置要求修改iis伺服器設定的,如果沒有自己的伺服器最好別這樣做,比較麻煩,可以使用“ashx”或者“axd”都可以。
<httpHandlers>
<add verb="*" path="chat.do" type="com.gs.chat.Chat, Game"/>
</httpHandlers>
下面是伺服器上將物件進行JSON序列化的程式,其實JSON序列化就是將一個物件轉換成有規律的字串,能夠被別人解讀出來,但不是所有的物件都能被序列化,一定要實現了ISerializable介面的類才行,可以參考Hashtable類,這個類就實現了ISerializable介面中的GetObjectData方法,因此這個型別的物件進行反序列化是沒有問題的。
using ...
using System.Web.Script.Serialization;
using ...
...
/// <summary>
/// 向客戶端返回的資料
/// 預設採用json編碼格式
/// </summary>
/// <param name="_result">伺服器方法的方會物件</param>
/// <returns>返回字串</returns>
public virtual string JsonResult(object _result)
{
//返回的字串
string resultString = "";
//採用了微軟的序列化方式
JavaScriptSerializer jss = new JavaScriptSerializer();
resultString = jss.Serialize(_result);
return resultString;
}
/// <summary>
/// 反序列化,從JSON字串轉換到物件
/// </summary>
/// <param name="_jsonstring">JSON串</param>
/// <returns>反序列化得到的物件</returns>
public virtual object JsonObject(string _jsonstring)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.DeserializeObject(_jsonstring);
}
...
輸出都是一樣的,直接Write:
context.Response.Write(_text);
這裡對於伺服器的開發方法可以很多,比如在同一個IHttpHandle中可以寫多個處理程式,分別處理不同的請求,然後有個專門的類負責分析要執行哪個方法。下面是傳送和接收聊天訊息的方法,供參考:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using com.Flight.Web.Ajax;
using System.Text.RegularExpressions;
namespace com.gs.chat
{
public class Chat : AjaxController
{
protected void Page_Load(object sender, EventArgs e)
{
AjaxJsBuilder.RegistType(typeof(Chat));
StartProcess();
}
[SafeMethod("A")]
[AjaxMethod()]
public Hashtable SendMessage(string _msg)
{
string patternForCmd = @"-\|cmd:[a-zA-z]+\|-";
Regex rg = new Regex(patternForCmd, RegexOptions.IgnoreCase | RegexOptions.Singleline);
Match m = rg.Match(_msg);
if (m.Success)
{
string cmd = m.Value;
if (cmd.ToLower().Equals("-|cmd:clear|-"))
{
MessageContainer.MsgContainer.Clear();
}
}
else
{
Message msg = new Message("me", "all", _msg, ToType.ALL);
MessageContainer.MsgContainer.Add(msg);
}
Hashtable rht = new Hashtable();
rht.Add("stat", "OK");
rht.Add("msg", "傳送成功。");
return rht;
}
[SafeMethod("A")]
[AjaxMethod()]
public MessageContainer ReceiveMessage(string _u)
{
MessageContainer mc = new MessageContainer();
foreach (Message msg in MessageContainer.MsgContainer)
{
if (msg.From.Equals(_u) || msg.To.Equals(_u))
{
mc.Add(msg);
}
}
return mc;
}
}
}
AjaxController這個類是自己寫的,從page繼承,用來做一些基本處理,比如JSON序列化啊,反序列化啊,安全檢查啊,還有分析客戶端要呼叫的方法之類,後面也會提到一些裡面的具體設計。
下面看看客戶端的開發,首先是向伺服器傳送請求,這個比較簡單,直接貼一個簡單例子,應該都明白
import flash.net.URLLoader;
import flash.net.URLRequest;
var request:URLRequest = new URLRequest(url);
var loader:URLLoader = new URLLoader();
var request_data:String = ajax_flag + "&" + method_flag + method + "&" + parameters;
request.data = request_data;
request.method = URLRequestMethod.POST;
loader.load(request);
主要是在loader的complete事件中處理的時候要注意把伺服器返回的字串進行JSON反序列化,轉換成物件,程式碼如下:
import com.adobe.serialization.json.JSON; //匯入使用的到類
在load_complete事件裡面寫如下程式碼:
//從事件物件想讀取伺服器返回的資料,反序列化為物件
var receiveMsg:Object = JSON.decode(event.target.data);
獲取receiveMsg物件之後就可以通過點操作符訪問屬性資料了。以一個HashTable為例,其中的Key就是反序列化後物件的屬性,Value就是屬性值。
在C#中能夠被直接序列化的容器物件很多,可以更具需要選擇,如果都不能滿足你的要求,也可以自己寫一個物件,實現ISerializable介面的GetObjectData方法進行資料傳輸。
按照上面的實現思路,如果一個IHttpHandle只能處理一種請求那麼我們就要寫出很多很多的IHttpHandle這樣就無法和webservice相提並論了,因為我們知道在webservice中一個service可以提供多個方法響應客戶端的請求,這個其實只要我們稍作處理就可以了,比如上面的例子裡面我們看到請求字串中包含了一些特殊的引數:
ajax_flag + "&" + method_flag + method
可以很容易看出來,這裡就是用來告訴伺服器我要呼叫哪些方法的引數。
注意:伺服器方法在響應請求之前還要做安全判斷,這個判斷很重要,否則隨便就能呼叫伺服器程式那豈不太危險?這裡給出一個簡單的解決方法,可以採用一個HttpModule做前端判斷,如果已經登入,請求引數中沒有特殊的符號(防止注入),並且有訪問這個HttpHandle的許可權那麼繼續,然後在HttpHandle中給指定的方法加個安全特性程式碼如下:
[SafeMethod("A")]
[AjaxMethod()]
public MessageContainer ReceiveMessage(string _u)
{
MessageContainer mc = new MessageContainer();
foreach (Message msg in MessageContainer.MsgContainer)
{
if (msg.From.Equals(_u) || msg.To.Equals(_u))
{
mc.Add(msg);
}
}
return mc;
}
[AjaxMethod()]和[SafeMethod("A")]這兩個特性說明ReceiveMessage方法是允許客戶端呼叫的,並且使用者具有特性A的時候才能執行這個方法,否則報錯。
相關文章
- HTTP通訊協議HTTP協議
- web通訊協議Web協議
- 在Go和Python之間通過ActiveMQ通訊GoPythonMQ
- HTTP協議的通訊框架HTTP協議框架
- 網路通訊協議-HTTP協議詳解!協議HTTP
- QT使用 http 協議通訊的實現示例QTHTTP協議
- WEB伺服器之HTTP協議Web伺服器HTTP協議
- HTTP協議之:HTTP/1.1和HTTP/2HTTP協議
- Tcp, WebSocket 和 http 之間的通訊TCPWebHTTP
- Django之web應用與http協議DjangoWebHTTP協議
- 網路通訊協議自動轉換之thrift到http協議HTTP
- CTFHUB技能樹之WEB前置技能HTTP協議WebHTTP協議
- 在 OpenResty 裡實現程式間通訊REST
- netty系列之:在netty中使用protobuf協議Netty協議
- C# wm6透過udp協議和pc通訊C#UDP協議
- Linux 下的程式間通訊:使用管道和訊息佇列Linux佇列
- netty系列之:protobuf在UDP協議中的使用NettyUDP協議
- web應用與http協議WebHTTP協議
- Web基礎與HTTP協議WebHTTP協議
- WEB基礎及HTTP協議WebHTTP協議
- 02 前端HTTP協議(圖解HTTP) 之 簡單的HTTP協議前端HTTP協議圖解
- 通訊協議協議
- JavaWeb第五講 Web核心基礎之HTTP協議JavaWebHTTP協議
- HTTP和HTTPS協議HTTP協議
- RPC和 HTTP協議RPCHTTP協議
- netty系列之:在netty中使用native傳輸協議Netty協議
- java web中jsp和action之間通訊小結JavaWebJS
- HTTP協議訊息頭HTTP協議
- C#使用MQTT通訊協議釋出訂閱主題報文C#MQQT協議
- 使用 JSON 協議的 gRPCJSON協議RPC
- Web快取 – HTTP協議快取Web快取HTTP協議
- Android 程式之間通訊Android
- 03 前端HTTP協議(圖解HTTP) 之 HTTP報文內的HTTP資訊前端HTTP協議圖解
- Linux 下的程式間通訊:套接字和訊號Linux
- 通訊協議和網路協議有什麼區別協議
- 在 .NET 中使用 OPC UA 協議協議
- 在nginx中使用proxy protocol協議NginxProtocol協議
- Redis 通訊協議Redis協議
- modbus通訊協議協議