Skip to content

Commit

Permalink
接口只有一个入参时,客户端可能用基础类型封包传递
Browse files Browse the repository at this point in the history
  • Loading branch information
nnhy committed Nov 11, 2023
1 parent 2c54f3a commit f58dd48
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 33 deletions.
2 changes: 2 additions & 0 deletions NewLife.Remoting/ApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace NewLife.Remoting;
/// <remarks>
/// 保持到服务端直接的长连接RPC通信。
/// 常用于向服务端发送请求并接收应答,也可以接收服务端主动发送的单向消息。
///
/// 文档 https://newlifex.com/core/srmp
/// </remarks>
public class ApiClient : ApiHost, IApiClient
{
Expand Down
4 changes: 3 additions & 1 deletion NewLife.Remoting/Http/HttpEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ public class HttpEncoder : EncoderBase, IEncoder
/// <param name="data"></param>
/// <param name="msg"></param>
/// <returns></returns>
public virtual IDictionary<String, Object?>? DecodeParameters(String action, Packet data, IMessage msg)
public virtual IDictionary<String, Object?>? DecodeParameters(String action, Packet? data, IMessage msg)
{
if (data == null || data.Total == 0) return null;

/*
* 数据内容解析需要根据http数据类型来判定使用什么格式处理
* **/
Expand Down
64 changes: 36 additions & 28 deletions NewLife.Remoting/IApiHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ public class ApiHandler : IApiHandler
}
else
{
var ps = ctx.ActionParameters;
rs = controller.InvokeWithParams(api.Method, ps as IDictionary);
rs = controller.InvokeWithParams(api.Method, ctx.ActionParameters as IDictionary);
}
ctx.Result = rs;
}
Expand Down Expand Up @@ -155,56 +154,65 @@ public virtual ControllerContext Prepare(IApiSession session, String action, Pac
ctx.Request = args;

// 如果服务只有一个二进制参数,则走快速通道
if (!api.IsPacketParameter)
{
// 不允许参数字典为空
var dic = args == null || args.Total == 0 ?
new NullableDictionary<String, Object?>(StringComparer.OrdinalIgnoreCase) :
enc.DecodeParameters(action, args, msg);
if (dic != null)
{
ctx.Parameters = dic;
//session.Parameters = dic;
if (api.IsPacketParameter) return ctx;

// 令牌,作为参数或者http头传递
if (dic.TryGetValue("Token", out var token)) session.Token = token + "";
if (session.Token.IsNullOrEmpty() && msg is HttpMessage hmsg && hmsg.Headers != null)
{
// post、package、byte三种情况将token 写入请求头
if (hmsg.Headers.TryGetValue("x-token", out var token2))
session.Token = token2;
else if (hmsg.Headers.TryGetValue("Authorization", out token2))
session.Token = token2.TrimStart("Bearer ");
}
// 不允许参数字典为空。接口只有一个入参时,客户端可能用基础类型封包传递
IDictionary<String, Object?>? dic = null;
if (args != null && args.Total > 0) dic = enc.DecodeParameters(action, args, msg);
dic ??= new NullableDictionary<String, Object?>(StringComparer.OrdinalIgnoreCase);
if (dic != null)
{
ctx.Parameters = dic;
//session.Parameters = dic;

// 准备好参数
var ps = GetParams(api.Method, dic, enc);
ctx.ActionParameters = ps;
// 令牌,作为参数或者http头传递
if (dic.TryGetValue("Token", out var token)) session.Token = token + "";
if (session.Token.IsNullOrEmpty() && msg is HttpMessage hmsg && hmsg.Headers != null)
{
// post、package、byte三种情况将token 写入请求头
if (hmsg.Headers.TryGetValue("x-token", out var token2))
session.Token = token2;
else if (hmsg.Headers.TryGetValue("Authorization", out token2))
session.Token = token2.TrimStart("Bearer ");
}

// 准备好参数
var ps = GetParams(api.Method, dic, args, enc);
ctx.ActionParameters = ps;
}

return ctx;
}

/// <summary>获取参数</summary>
/// <param name="method"></param>
/// <param name="dic"></param>
/// <param name="args"></param>
/// <param name="encoder"></param>
/// <returns></returns>
protected virtual IDictionary<String, Object?> GetParams(MethodInfo method, IDictionary<String, Object?> args, IEncoder encoder)
protected virtual IDictionary<String, Object?> GetParams(MethodInfo method, IDictionary<String, Object?> dic, Packet? args, IEncoder encoder)
{
var ps = new Dictionary<String, Object?>();

// 该方法没有参数,无视外部传入参数
var pis = method.GetParameters();
if (pis == null || pis.Length <= 0) return ps;

// 接口只有一个入参时,客户端可能用基础类型封包传递
if (pis.Length == 1 && dic == null && args != null)
{
var pi = pis[0];
ps[pi.Name] = args.ToStr().ChangeType(pi.ParameterType);

return ps;
}

foreach (var pi in pis)
{
var name = pi.Name;

Object? v = null;
if (args != null && args.ContainsKey(name)) v = args[name];
if (dic != null && dic.TryGetValue(name, out var v2)) v = v2;

// 基本类型
if (pi.ParameterType.GetTypeCode() != TypeCode.Object)
Expand All @@ -219,7 +227,7 @@ public virtual ControllerContext Prepare(IApiSession session, String action, Pac
ps[name] = Convert.FromBase64String(v + "");
else
{
v ??= args;
v ??= dic;
if (v != null)
ps[name] = encoder.Convert(v, pi.ParameterType);
}
Expand Down
3 changes: 3 additions & 0 deletions NewLife.Remoting/IApiServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
namespace NewLife.Remoting;

/// <summary>应用接口服务器接口</summary>
/// <remarks>
/// 文档 https://newlifex.com/core/srmp
/// </remarks>
public interface IApiServer
{
/// <summary>主机</summary>
Expand Down
4 changes: 2 additions & 2 deletions NewLife.Remoting/IEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public interface IEncoder
/// <param name="data">数据</param>
/// <param name="msg">消息</param>
/// <returns></returns>
IDictionary<String, Object?>? DecodeParameters(String action, Packet data, IMessage msg);
IDictionary<String, Object?>? DecodeParameters(String action, Packet? data, IMessage msg);

/// <summary>解码结果</summary>
/// <param name="action"></param>
Expand Down Expand Up @@ -105,6 +105,6 @@ public abstract class EncoderBase
/// <summary>写日志</summary>
/// <param name="format"></param>
/// <param name="args"></param>
public virtual void WriteLog(String format, params Object[] args) => Log?.Info(format, args);
public virtual void WriteLog(String format, params Object?[] args) => Log?.Info(format, args);
#endregion
}
9 changes: 7 additions & 2 deletions NewLife.Remoting/JsonEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,16 @@ public virtual Packet Encode(String action, Int32 code, Packet? value)
/// <param name="data">数据</param>
/// <param name="msg">消息</param>
/// <returns></returns>
public IDictionary<String, Object?>? DecodeParameters(String action, Packet data, IMessage msg)
public IDictionary<String, Object?>? DecodeParameters(String action, Packet? data, IMessage msg)
{
var json = data.ToStr();
if (data == null || data.Total == 0) return null;

var json = data.ToStr().Trim();
WriteLog("{0}[{2:X2}]<={1}", action, json, msg is DefaultMessage dm ? dm.Sequence : 0);

// 接口只有一个入参时,客户端可能用基础类型封包传递
if (json.IsNullOrEmpty() || json[0] != '{' && json[1] != '[') return null;

return JsonParser.Decode(json);
}

Expand Down

0 comments on commit f58dd48

Please sign in to comment.