如何使用简单的服务端去接收数据

cs 复制代码
private async Task ProcessRequestAsync(HttpListenerContext context)
{
    try
    {
        var request = context.Request;
        var response = context.Response;

        // 步骤1:只处理POST请求
        if (request.HttpMethod != "POST")
        {
            response.StatusCode = 405;
            await WriteSimpleResponse(response, "只支持POST请求");
            return;
        }

        // 步骤2:读取并解析请求数据
        string jsonBody = await ReadRequestBody(request);
        dynamic data = ParseJson(jsonBody);
        
        if (data == null)
        {
            response.StatusCode = 400;
            await WriteSimpleResponse(response, "无效的JSON数据");
            return;
        }

        // 步骤3:验证必要字段
        if (string.IsNullOrEmpty(data.method?.ToString()) || 
            string.IsNullOrEmpty(data.reqCode?.ToString()))
        {
            await WriteErrorResponse(response, data?.reqCode, "缺少method或reqCode字段");
            return;
        }

        // 步骤4:查找对应工位
        int stationIndex = FindStationIndex(data.reqCode.ToString());
        if (stationIndex == -1)
        {
            await WriteErrorResponse(response, data.reqCode, "未找到对应的工位配置");
            return;
        }

        // 步骤5:根据方法类型处理
        string method = data.method.ToString();
        bool success = await ExecuteStationAction(method, stationIndex);
        
        if (success)
        {
            await WriteSuccessResponse(response, data.reqCode);
        }
        else
        {
            await WriteErrorResponse(response, data.reqCode, "执行操作失败");
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"处理请求错误: {ex.Message}");
    }
    finally
    {
        context.Response.Close();
    }
}

// 辅助方法
private async Task<string> ReadRequestBody(HttpListenerRequest request)
{
    using var reader = new StreamReader(request.InputStream, request.ContentEncoding);
    return await reader.ReadToEndAsync();
}

private dynamic ParseJson(string json)
{
    try
    {
        return JsonConvert.DeserializeObject(json);
    }
    catch
    {
        return null;
    }
}

private int FindStationIndex(string requestCode)
{
    var configs = FrmConfig.GetInstance().taskConfigs;
    for (int i = 0; i < configs.Count; i++)
    {
        if (configs[i] == requestCode) return i;
    }
    return -1;
}

private async Task<bool> ExecuteStationAction(string method, int stationIndex)
{
    try
    {
        switch (method)
        {
            case "Wait":
                int address = PlcCommunication.GetInstance().plcAddressOffset(stationIndex);
                PlcCommunication.GetInstance().myPLC.WriteSingleRegister((ushort)address, 3);
                Log($"发送继续信号到工位{stationIndex}");
                return true;
                
            case "Arrive":
                FrmShow.stationInfos[stationIndex].Status = 0;
                Log($"工位{stationIndex}任务完成,状态重置");
                return true;
                
            default:
                Log($"未知方法: {method}");
                return false;
        }
    }
    catch (Exception ex)
    {
        Log($"执行失败: {ex.Message}");
        return false;
    }
}

private void Log(string message)
{
    Console.WriteLine($"[{DateTime.Now}] {message}");
    FrmShow.GetInstance()?.ucLogShow?.LogInfo(message);
}

private async Task WriteSimpleResponse(HttpListenerResponse response, string message)
{
    await WriteJsonResponse(response, new { code = "error", message });
}

private async Task WriteSuccessResponse(HttpListenerResponse response, object reqCode)
{
    await WriteJsonResponse(response, new { reqCode, code = "0", message = "成功" });
}

private async Task WriteErrorResponse(HttpListenerResponse response, object reqCode, string message)
{
    await WriteJsonResponse(response, new { reqCode, code = "99", message });
}

ProcessRequestAsync (主入口)

ReadRequestBody → 读取HTTP请求体

ParseJson → 解析JSON为对象

FindStationIndex → 查找工位索引

ExecuteStationAction → 执行具体操作

├── Wait操作 → 写入PLC

└── Arrive操作 → 更新状态

WriteSuccessResponse/WriteErrorResponse → 返回响应

Log → 记录日志

方法作用详细解释

让我逐一解释每个方法的作用:

1. 主处理方法 - ProcessRequestAsync

cs 复制代码
private async Task ProcessRequestAsync(HttpListenerContext context)

作用:这是HTTP请求的主处理器,负责协调整个请求处理流程。

执行流程

  1. 步骤1:检查是否是POST请求,不是则返回405错误

  2. 步骤2:读取并解析JSON请求体

  3. 步骤3:验证必要字段(method和reqCode)

  4. 步骤4:根据reqCode查找对应的工位

  5. 步骤5:根据method类型执行具体操作

  6. 步骤6:返回成功或失败响应

2. 读取请求体 - ReadRequestBody

cs 复制代码
private async Task<string> ReadRequestBody(HttpListenerRequest request)
{
    using var reader = new StreamReader(request.InputStream, request.ContentEncoding);
    return await reader.ReadToEndAsync();
}

作用:从HTTP请求中读取完整的请求体内容。

工作原理解释

  • request.InputStream:获取请求的原始数据流(字节流)

  • StreamReader:将字节流转换为可读的文本

  • request.ContentEncoding:使用请求指定的编码方式(如UTF-8)

  • ReadToEndAsync():异步读取所有内容直到末尾

  • using:确保使用后自动释放资源

示例

javascript 复制代码
// 输入请求体
{"method":"Wait","reqCode":"STATION_01"}

// 方法返回
"{\"method\":\"Wait\",\"reqCode\":\"STATION_01\"}"

3. 解析JSON - ParseJson

cs 复制代码
private dynamic ParseJson(string json)
{
    try
    {
        return JsonConvert.DeserializeObject(json);
    }
    catch
    {
        return null;
    }
}

作用:将JSON字符串解析为动态对象,方便访问属性。

特点

  • 使用dynamic类型,可以直接访问属性(如data.method

  • 异常安全:解析失败返回null,不会抛出异常

  • 使用Newtonsoft.Json库(JsonConvert)

示例

cs 复制代码
// 输入
string json = "{\"method\":\"Wait\",\"reqCode\":\"STATION_01\"}";

// 输出(dynamic对象)
data.method   // "Wait"
data.reqCode  // "STATION_01"

4. 查找工位索引 - FindStationIndex

cs 复制代码
private int FindStationIndex(string requestCode)
{
    var configs = FrmConfig.GetInstance().taskConfigs;
    for (int i = 0; i < configs.Count; i++)
    {
        if (configs[i] == requestCode) return i;
    }
    return -1;
}

作用:根据请求码(reqCode)在配置列表中查找对应的工位索引。

工作原理

  • 从全局配置FrmConfig获取任务配置列表taskConfigs

  • 遍历列表,查找与requestCode匹配的项

  • 返回匹配项的索引位置

  • 找不到返回-1

示例

cs 复制代码
// taskConfigs 内容: ["STATION_01", "STATION_02", "STATION_03"]
FindStationIndex("STATION_02")  // 返回 1
FindStationIndex("STATION_05")  // 返回 -1

5. 执行工位操作 - ExecuteStationAction

cs 复制代码
private async Task<bool> ExecuteStationAction(string method, int stationIndex)

作用:根据方法类型执行具体的工位操作。

两种操作类型

Wait操作(任务等待)
cs 复制代码
case "Wait":
    int address = PlcCommunication.GetInstance().plcAddressOffset(stationIndex);
    PlcCommunication.GetInstance().myPLC.WriteSingleRegister((ushort)address, 3);
    Log($"发送继续信号到工位{stationIndex}");
    return true;
  • 计算PLC的偏移地址

  • 向PLC写入值3(继续任务信号)

  • 记录操作日志

Arrive操作(任务完成)
cs 复制代码
case "Arrive":
    FrmShow.stationInfos[stationIndex].Status = 0;
    Log($"工位{stationIndex}任务完成,状态重置");
    return true;
  • 将工位状态重置为0(空闲状态)

  • 记录操作日志

6. 日志记录 - Log

cs 复制代码
private void Log(string message)
{
    Console.WriteLine($"[{DateTime.Now}] {message}");
    FrmShow.GetInstance()?.ucLogShow?.LogInfo(message);
}

作用:同时向控制台和UI界面记录日志信息。

特点

  • 添加时间戳

  • 同时输出到控制台和UI日志控件

  • 使用?.安全调用,防止空引用

7. 响应处理方法

简单响应 - WriteSimpleResponse
cs 复制代码
private async Task WriteSimpleResponse(HttpListenerResponse response, string message)
{
    await WriteJsonResponse(response, new { code = "error", message });
}

作用:返回简单的错误响应(无reqCode)

输出示例

javascript 复制代码
{"code":"error","message":"只支持POST请求"}
成功响应 - WriteSuccessResponse
cs 复制代码
private async Task WriteSuccessResponse(HttpListenerResponse response, object reqCode)
{
    await WriteJsonResponse(response, new { reqCode, code = "0", message = "成功" });
}

作用:返回操作成功的响应

输出示例

javascript 复制代码
{"reqCode":"STATION_01","code":"0","message":"成功"}
错误响应 - WriteErrorResponse
cs 复制代码
private async Task WriteErrorResponse(HttpListenerResponse response, object reqCode, string message)
{
    await WriteJsonResponse(response, new { reqCode, code = "99", message });
}

作用:返回操作失败的响应

输出示例

javascript 复制代码
{"reqCode":"STATION_01","code":"99","message":"未找到对应的工位配置"}

8. JSON响应写入 - WriteJsonResponse

(这是原有代码中的方法,不是新加的)

cs 复制代码
private async Task WriteJsonResponse(HttpListenerResponse response, object data)
{
    string json = System.Text.Json.JsonSerializer.Serialize(data);
    byte[] buffer = Encoding.UTF8.GetBytes(json);
    
    response.ContentType = "application/json";
    response.ContentLength64 = buffer.Length;
    
    await response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
}

作用:将对象序列化为JSON并写入HTTP响应

相关推荐
是五月吖1 小时前
【C#】SOLID原则
c#
人工智能AI技术3 小时前
两会“人工智能+“风口已至:C#开发者用Semantic Kernel搭建企业级Agent的3个实战套路
人工智能·c#
进击的编程阿伟6 小时前
C#开发工程师-面经
面试·c#
缺点内向6 小时前
C#实战:使用Spire.XLS for .NET 将Excel转换为SVG图片
c#·自动化·.net·excel
小曹要微笑7 小时前
C#的运算符重载
开发语言·c#·运算符重载·c#运算符重载
我是唐青枫7 小时前
C#.NET Channel 深入解析:高性能异步生产者消费者模型实战
开发语言·c#·.net
Crazy Struggle7 小时前
C# + ViewFaceCore 快速实现高精度人脸识别
c#·人脸识别·.net·开源项目
小曹要微笑7 小时前
委托(Delegate)在C#中的概念与应用
前端·javascript·c#
人工智能AI技术8 小时前
Oracle裁员3万人的警钟:C#程序员如何构建AI工具链反杀,从“被替代“到“驾驭AI“
人工智能·c#