您现在的位置是:首页 > 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的模板采用近似 PHP 表达式的语法,支持的元素如下:逻辑元素包围符,该符号用于包含条件和循环元素条件判断这是一个典型的条件模板,当条件 expr1 为真时
CentOs7搭建论坛Discuz_X3.2的步骤方法
由于公司项目需要一个互动平台,可以发起活动,发消息留言,讨论过后发现这竟然是一个论坛的功能。 于是就不打算耗费功夫开发相关功能,直接另外搭一套BBS算球。。。 一直觉得搭建B
discuz模板文件作用说明
template/default/common模板公共文件夹,全局相关|--block_forumtree.htm 树形论坛版块分支js文件|--block_thread.htm特殊主题的风格模块文件
Discuz快速安装部署常见报错及解决办法
准备环境、下载和解压软件包、配置数据库、运行安装程序。每个步骤都有可能遇到问题,但只要我们一步步来,就能顺利完成安装。
相关源码
-
(PC+WAP)聚氨酯粉末涂料防腐耐用材料粘合剂网站源码下载为化工涂料企业设计的展示系统,集成产品技术参数库、颜色样板展示器和配方查询模块。支持粉末涂料、环氧树脂等多类产品分类展示查看源码 -
帝国cms7.5自适应手机端在线课程教育网站源码基于帝国CMS后台管理系统,支持在线修改支付参数、联系方式等配置信息,操作界面直观便捷。专注于在线教育视频领域,提供完整的视频课程展示、付费购买及在线支付解决方案。支持多种支付渠道,满足教育培训机构的运营需求。查看源码 -
(PC+WAP)货物运输快递物流汽车贸易pbootcms模板下载为货运代理、汽车贸易及快递企业设计的全终端适配网站系统,整合运单追踪与车辆展示核心功能模块原生开发的DIV+CSS架构,支持WebP图像压缩技术。查看源码 -
帝国cms7.5模板生活常识美食女性时尚综合资讯门户源码本模板为帝国cms7.5生活资讯类网站设计,以天奇生活网为参考原型,涵盖生活常识、美食烹饪、女性时尚等多元化内容板块。采用响应式布局设计,适配各种终端设备,为访客提供优质的阅读体验。模板结构清晰合理,内容展示层次分明,符合生活类网站的用户需求。查看源码 -
(自适应响应式)绿色环保材料设备科技类营销型网站pbootcms源码下载本模板基于PbootCMS开发,主要面向环保设备、环保材料及相关科技企业。采用HTML5+CSS3技术构建,具备响应式特性,确保在各类设备上均有良好展示效果。查看源码 -
Wordpress博客新闻主题在线商店平台betheme 21.5.6版BeTheme是一款功能丰富的WordPress主题模板,专注于为各行业提供网站建设解决方案。该模板支持WooCommerce电子商务功能,能够快速搭建在线商店平台,同时适用于博客、新闻资讯类网站建设。自2014年发布以来,该模板已经获得大量用户的使用验证。查看源码
| 分享笔记 (共有 篇笔记) |
