您现在的位置是:首页 > cms教程 > Discuz教程Discuz教程
异步调用Discuz!NT接口的实现方法
寒云2025-07-07Discuz教程已有人查阅
导读最近在做Discuz!NT论坛与网站整合的东西,于是便用到了Discuz提供的Discuz! Toolkit看了看源码,应该说这是个不错的工具库,提供了关于注册
最近在做Discuz!NT论坛与网站整合的东西,于是便用到了Discuz提供的Discuz! Toolkit看了看源码,应该说这是个不错的工具库,提供了关于注册、登录、 文章、积分等论坛操作的一篮子功能,而且配备了对应的Wiki只可惜,Discuz!NT终归是异构的系统,响应速度和突发异常并非如自己的代码一样可控,使用同步方式调用API就显得有那么些不智了
好在Toolkit是开源的,可以DIY,看看它提供的同步访问Web Service方法:
1、调用开始等待响应
2、响应触发调用完成。
演化成语言:一个方法以委托的方式,在这两部分之间传递,第1部分会将方法指针(委托)塞入请求里,在流程执行到第2部分时,方法被取出回调。
先设计委托原型:
好在Toolkit是开源的,可以DIY,看看它提供的同步访问Web Service方法:
public static byte[] GetResponseBytes(string apiUrl, string method_name, string postData)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(apiUrl);
request.Method = "POST";
request.ContentType = "application/x- -form-urlencoded";
request.ContentLength = postData.Length;
request.Timeout = 20000;
HttpWebResponse response = null;
try
{
StreamWriter swRequestWriter = new StreamWriter(request.GetRequestStream());
swRequestWriter.Write(postData);
if (swRequestWriter != null)
swRequestWriter.Close();
response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
return Encoding.UTF8.GetBytes(reader.ReadToEnd());
}
}
finally
{
if (response != null)
response.Close();
}
}
要进行异步的调用,原本的同步流程会被切成两部分:1、调用开始等待响应
2、响应触发调用完成。
演化成语言:一个方法以委托的方式,在这两部分之间传递,第1部分会将方法指针(委托)塞入请求里,在流程执行到第2部分时,方法被取出回调。
先设计委托原型:
public delegate void GetResponseGeneric<T>(T objects);
异步请求数据结构:
public class RequestState
{
public HttpWebRequest request;
public HttpWebResponse response;
}
扩展一下Util工具类,加上异步调用接口方法:
/// <summary>
/// 异步获取响应开始
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fun">泛型回调方法</param>
/// <param name="method_name"></param>
/// <param name="parameters"></param>
#region void GetResponseBegin<T>(GetResponseGeneric<T> fun,string method_name, params DiscuzParam[] parameters)
public void GetResponseBegin<T>(GetResponseGeneric<T> fun,string method_name, params DiscuzParam[] parameters)
{
DiscuzParam[] signed = Sign(method_name, parameters);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < signed.Length; i++)
{
if (i > 0)
builder.Append("&");
builder.Append(signed.ToEncodedString());
}
//异步获取字节流
GetResponseBytesBegin<T>(fun,Url, method_name, builder.ToString());
}
#endregion
/// <summary>
/// 异步获取响应完成
/// </summary>
#region void GetReponseEnd<T>(GetResponseGeneric<T> fun,byte[] response_bytes)
public void GetReponseEnd<T>(GetResponseGeneric<T> fun, byte[] response_bytes)
{
XmlSerializer response_serializer = GetSerializer(typeof(T));
try
{
T response = (T)response_serializer.Deserialize(new MemoryStream(response_bytes));
//回调 调用方 接收方法
fun(response);
}
catch
{
Error error = (Error)ErrorSerializer.Deserialize(new MemoryStream(response_bytes));
throw new DiscuzException(error.ErrorCode, error.ErrorMsg);
}
}
#endregion
/// <summary>
/// 异步获取字节流开始
/// </summary>
/// <param name="callback">回调方法</param>
/// <param name="apiUrl"></param>
/// <param name="method_name"></param>
/// <param name="postData"></param>
#region void GetResponseBytesBegin<T>(GetResponseGeneric<T> fun,string apiUrl, string method_name, string postData)
private void GetResponseBytesBegin<T>(GetResponseGeneric<T> fun, string apiUrl, string method_name, string postData)
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(apiUrl);
request.Method = "POST";
request.ContentType = "application/x- -form-urlencoded";
request.ContentLength = postData.Length;
request.Timeout = 20000;
StreamWriter swRequestWriter = new StreamWriter(request.GetRequestStream());
swRequestWriter.Write(postData);
if (swRequestWriter != null)
swRequestWriter.Close();
RequestState myRequestState = new RequestState();
myRequestState.request = request;
//异步调用
request.BeginGetResponse(ar => GetResponseBytesEnd<T>(fun, ar), myRequestState);
}
#endregion
/// <summary>
/// 异步获取字节流完成
/// </summary>
/// <param name="asynchronousResult"></param>
#region void GetResponseBytesEnd<T>(GetResponseGeneric<T> fun,IAsyncResult asynchronousResult)
private void GetResponseBytesEnd<T>(GetResponseGeneric<T> fun, IAsyncResult asynchronousResult)
{
RequestState myRequestState = (RequestState)asynchronousResult.AsyncState;
HttpWebRequest myHttpWebRequest = myRequestState.request;
try
{
//接收完成
myRequestState.response = (HttpWebResponse)myHttpWebRequest.EndGetResponse(asynchronousResult);
using (StreamReader reader = new StreamReader(myRequestState.response.GetResponseStream(), Encoding.UTF8))
{
byte[] response_bytes = Encoding.UTF8.GetBytes(reader.ReadToEnd());
//回调 异步获取响应完成 方法
GetReponseEnd<T>(fun, response_bytes);
}
}
catch (WebException ex)
{
DiscuzLogger.WriteLog(typeof(Util), ex);
}
finally
{
if (myRequestState.response != null)
myRequestState.response.Close();
}
}
#endregion
/// <summary>
/// 异步 获取主题列表 开始
/// </summary>
/// <param name="fid"></param>
/// <param name="page_size"></param>
/// <param name="page_index"></param>
/// <returns></returns>
public void GetTopicListBegin(GetResponseGeneric<TopicGetListResponse> fun,
int fid, int page_size, int page_index, string typeIdList)
{
List<DiscuzParam> param_list = new List<DiscuzParam>();
if (session_info != null && !string.IsNullOrEmpty(session_info.SessionKey))
{
param_list.Add(DiscuzParam.Create("session_key", session_info.SessionKey));
}
param_list.Add(DiscuzParam.Create("type_id_list", typeIdList));
param_list.Add(DiscuzParam.Create("fid", fid));
param_list.Add(DiscuzParam.Create("page_size", page_size));
param_list.Add(DiscuzParam.Create("page_index", page_index));
//异步开始
util.GetResponseBegin<TopicGetListResponse>(fun, "topics.getList", param_list.ToArray());
}
调用方使用起来只需要定义好接收方法,剩下就是收数据(CacheObjectCollection.HomepageTopicList是一个缓存项的getter/setter):
/// <summary>
/// 异步获取论坛指定板块的帖子列表开始
/// </summary>
/// <param name="fid">板块ID</param>
/// <param name="pageSize">数量</param>
/// <param name="pageIndex">索引</param>
/// <param name="typeIdList">主题ID 以 , 为分隔符</param>
#region static void HomepageTopicGetBegin(int fid, int pageSize, int pageIndex, string typeIdList)
public static void HomepageTopicGetBegin(int fid, int pageSize, int pageIndex, string typeIdList)
{
if (CacheObjectConllection.HomepageTopicList == null)
{
try
{
DiscuzSession session = GetSession();
session.GetTopicListBegin(HomepageTopicGetEnd, fid, pageSize, pageIndex, typeIdList);
}
catch (DiscuzException ex)
{
Logger.WriteLog(typeof(DiscuzHelper),
string.Format("DISCUZ!NT异步获取论坛指定板块的帖子列表错误:\r\n{0}"
, ex.ToString()));
}
}
}
#endregion
/// <summary>
/// 异步获取论坛指定板块的帖子列表完成
/// </summary>
#region static void HomepageTopicGetEnd(TopicGetListResponse result)
public static void HomepageTopicGetEnd(TopicGetListResponse result)
{
CacheObjectConllection.HomepageTopicList = result;
}
#endregion
到此,异步调用框架完成,个人感觉很好。
本文标签:
很赞哦! ()
下一篇:Discuz数据库结构表说明
相关教程
图文教程
怎么用discuz门户,discuz门户是什么
Discuz门户是基于Discuz论坛系统开发的门户 CMS,为社区网站提供了新闻发布、文章管理、自定义页面等功能。使用指南包括:安装Discuz门户插件添加新闻和文章创建自定义
Discuz NT相册查看插件开发实例
现在把他整合在Discuz NT 的相册程序中.下面介绍一下实现方法. 貌似太简单了点.然后在discuz NT网站的根目录下新建一个文件夹来放highslide库, 我这里是命名为static
Discuz论坛使用时页面卡顿的解决方法
当你刚开始使用Discuz论坛时,可能会遇到页面卡顿的问题,这不仅影响用户体验,还可能让新手望而却步。Discuz作为一个功能强大的开源论坛系统,支持众多插件和主题
自动登录DISCUZ发帖的实现方法示例
有点无聊的东西,不是通用的,不过RD提供了我们论坛用的discuz的hashform的计算代码,也许通用的DISCUZ灌水机器人是我这种菜鸟也能搞出来的。
相关源码
-
(自适应响应式)黑色酷炫高端数码摄影pbootcms网站模板源码本模板基于PbootCMS开发,为摄影工作室、个人摄影师及摄影爱好者设计。采用深色系风格,突出摄影作品展示效果,适配各类数码设备浏览。适用于作品集展示查看源码 -
(自适应响应式)html5蓝色智能水表营销型网站pbootcms模板下载PbootCMS内核开发,为智能水表企业打造的营销型网站解决方案,本模板基于PbootCMS内核开发,为智能水表及相关行业企业设计,采用HTML5+CSS3技术构建,具有响应式布局。查看源码 -
快递物流公司pbootcms网站模板html响应式自适应源码下载基于HTML5+CSS3前沿技术开发,实现PC、平板、手机多端自适应。采用弹性布局与媒体查询技术,确保不同设备均有流畅视觉体验,企业形象统一。查看源码 -
(PC+WAP)蓝色自动电动闸门伸缩门类网站pbootcms模板下载为电动闸门、自动伸缩门企业设计的响应式网站模板,突出产品展示与技术优势,助力门控设备企业建立专业数字化形象。手工编写DIV+CSS结构,代码精简高效,无冗余代码干扰,加载速度更快。查看源码 -
(PC+WAP)门窗门业家居定制铝合金产品pbootcms模板下载基于PbootCMS内核开发的门窗门业企业专用模板,采用响应式设计结构,数据一次录入即可同步适配电脑与手机端浏览。通过简洁大气的视觉呈现,帮助门窗企业快速建立专业线上展示平台,有效传递产品价值与服务优势。查看源码 -
自适应营销型IT网络工作室互联网建站公司pbootcms网站模板为IT网络服务商、建站企业打造的高性能营销门户,基于PbootCMS开源内核深度开发采用HTML5自适应架构,实现PC与手机端数据实时同步交互。查看源码
| 分享笔记 (共有 篇笔记) |
