
简介本资源为WMS与WCS系统对接的发送任务代码实现面向仓储物流系统开发人员及自动化立体库集成工程师重点解决WMS向WCS下发入库、出库、移库指令的通信协议与数据结构问题。资源包共2000个文件以dll动态库、cshtml页面、js脚本、cs源码、css样式及xml、config配置文件为主另有png、jpg等界面素材压缩包约367MB完整呈现了任务报文从定义到调度的工程结构。代码中清晰定义了cmd指令101入库、102出库、103移库、seq序号、task_id唯一任务编码以及src_station、dest_station站台与src_rack、src_col、src_row、dest_rack、dest_col、dest_row等排、列、层坐标字段并包含weight重量与barcode条码信息便于读者理解WCS任务解析与货位定位逻辑。目前已有2355人学习下载适合需要搭建WMS-WCS通信链路、调试任务下发流程或研究仓储调度协议的开发者参考借鉴。1. WMS 到 WCS 的任务下发一条指令从点击到落地的全链路电商仓库里拣货员在 PDA 上点下“确认出库”的那一刻背后其实发生了一连串看不见的接力WMS 生成出库单拆成若干条搬运任务再逐条下发给 WCSWCS 把任务翻译成输送线、堆垛机、AGV 能听懂的动作指令。这条链路里WMS 是大脑WCS 是脊髓任务下发就是神经信号。信号传丢了货就卡在半路信号传重了设备可能撞车。很多做 wms 系统的朋友业务逻辑写得飞起一到和 WCS 对接就翻车问题往往出在任务模型没对齐、状态机没闭环、异常没兜底。这篇笔记就围绕“WMS 向 WCS 发送任务”这个动作把接口设计、任务结构、状态回传、并发控制和踩坑记录一次讲透适合正在做 WMS/WCS 对接的开发和实施人员。2. 任务下发前必须对齐的三件事模型、协议、状态机2.1 任务模型WMS 的“出库单”和 WCS 的“搬运指令”不是一回事WMS 眼里的世界是订单、SKU、库存、波次WCS 眼里的世界是起点、终点、容器、设备动作。WMS 说“把 A 货架的 3 号箱子送到打包台”WCS 需要的是“输送线段 12 启动方向正向目标位置打包台入口容器条码 C003”。如果直接把 WMS 的出库单 JSON 扔给 WCS对方大概率解析失败。常见做法是定义一层“任务中间模型”把 WMS 的业务语义翻译成 WCS 能执行的原子动作。这个模型通常包含这些字段字段名含义示例注意点taskIdWMS 侧唯一任务号OUT-20250101-0001必须全局唯一建议带业务前缀taskType任务类型OUTBOUND / MOVE / PICK枚举值双方约定死containerCode容器条码C003空托盘也要传占位符fromLocation起点位置编码A-01-03-02必须和 WCS 位置字典一致toLocation终点位置编码PACK-01同上priority优先级50数值越小越优先范围 1-99createTime创建时间2025-01-01 10:00:00用于超时判断这个表不是拍脑袋定的是我在三个项目里被 WCS 厂商打回来两次之后才稳定下来的。关键点是位置编码必须用 WCS 的位置字典不能自己编容器条码要区分“实体容器”和“虚拟容器”优先级字段一定要有否则高峰期任务全堵在入口。2.2 通信协议HTTP 还是 TCP同步还是异步WMS 和 WCS 之间的通信常见的有三种HTTP RESTful、TCP Socket 长连接、消息队列。选哪种取决于 WCS 厂商的既有能力和实时性要求。HTTP 接口最简单WMS 发一个 POST 请求WCS 返回接收成功或失败。但问题是同步阻塞如果 WCS 处理慢WMS 线程会被挂住。我一般会加一个超时时间比如 3 秒超时后把任务标记为“待确认”由后台定时任务去查 WCS 的任务状态。TCP Socket 实时性最好适合输送线这种毫秒级响应的场景。但需要自己处理粘包、断线重连、心跳。代码量不小而且调试麻烦。消息队列比如 RabbitMQ、Kafka是折中方案WMS 把任务丢进队列就返回WCS 自己消费。解耦彻底但引入了中间件运维成本而且消息丢失或重复消费需要额外处理。我的建议是如果 WCS 厂商提供了 HTTP 接口优先用 HTTP 异步确认如果没有再考虑 TCP消息队列适合多 WCS 实例或跨机房场景。2.3 状态机任务从“创建”到“完成”要经过几个状态任务下发不是一锤子买卖WMS 需要知道任务在 WCS 那边走到哪一步了。常见状态包括CREATEDWMS 已创建尚未下发SENT已发送给 WCS等待确认ACCEPTEDWCS 已接收排队中EXECUTING设备正在执行COMPLETED任务完成FAILED执行失败CANCELLED人工取消WMS 侧的状态机必须和 WCS 侧对齐否则会出现“WMS 以为完成了WCS 还在跑”的尴尬。我习惯在 WMS 里加一个“状态回查”定时任务每隔 5 秒去 WCS 拉一次未完成任务的状态防止消息丢失导致状态卡死。3. 用 HTTP 接口把任务从 WMS 推到 WCS代码级实现3.1 任务组装从出库单到 WCS 任务对象的转换假设 WMS 已经生成了一个出库单现在要把它拆成若干条搬运任务。下面是一个 Python 示例把出库单明细转换成 WCS 任务列表import json import requests from datetime import datetime def build_wcs_tasks(outbound_order): 将 WMS 出库单转换为 WCS 任务列表 outbound_order: dict包含 orderId, details 列表 每个 detail: {sku, qty, fromLocation, toLocation, containerCode} tasks [] for idx, detail in enumerate(outbound_order[details]): task { taskId: f{outbound_order[orderId]}-{idx:03d}, taskType: OUTBOUND, containerCode: detail.get(containerCode, VIRTUAL), fromLocation: detail[fromLocation], toLocation: detail[toLocation], priority: outbound_order.get(priority, 50), createTime: datetime.now().strftime(%Y-%m-%d %H:%M:%S), callbackUrl: http://wms-host/api/wcs/callback # WCS 回调地址 } tasks.append(task) return tasks这段代码的关键点taskId 用订单号加序号保证唯一且可追溯containerCode 如果为空用 VIRTUAL 占位避免 WCS 解析报错callbackUrl 是告诉 WCS 完成任务后回调哪个接口这样 WMS 不用轮询。3.2 发送任务带重试和超时的 HTTP 请求组装好任务后逐条发送给 WCS。下面是一个带重试机制的发送函数def send_task_to_wcs(task, wcs_url, max_retries3, timeout3): 发送单个任务到 WCS失败重试 wcs_url: WCS 接收任务的接口地址 max_retries: 最大重试次数 timeout: 单次请求超时秒数 headers {Content-Type: application/json} for attempt in range(max_retries): try: resp requests.post( wcs_url, datajson.dumps(task), headersheaders, timeouttimeout ) if resp.status_code 200: result resp.json() if result.get(code) SUCCESS: return True, result.get(wcsTaskId) else: # 业务失败不重试直接返回错误 return False, result.get(message) else: # HTTP 错误继续重试 continue except requests.exceptions.Timeout: # 超时继续重试 continue except requests.exceptions.ConnectionError: # 连接错误继续重试 continue return False, 发送失败已重试{}次.format(max_retries)参数说明max_retries 建议设为 3太多会拖慢整体流程timeout 设为 3 秒因为 WCS 接收任务通常很快超过 3 秒大概率是网络或 WCS 卡了。注意区分“HTTP 错误”和“业务失败”HTTP 错误可以重试业务失败比如位置编码不存在重试也没用直接返回错误让上层处理。3.3 状态回传WCS 如何把执行结果告诉 WMSWCS 完成任务后需要回调 WMS 的接口。WMS 侧要提供一个接收回调的接口更新任务状态。下面是一个 Flask 示例from flask import Flask, request, jsonify app Flask(__name__) app.route(/api/wcs/callback, methods[POST]) def wcs_callback(): data request.json task_id data.get(taskId) status data.get(status) # COMPLETED / FAILED wcs_task_id data.get(wcsTaskId) if not task_id or not status: return jsonify({code: FAIL, message: 参数缺失}), 400 # 更新 WMS 任务状态 # update_task_status(task_id, status, wcs_task_id) return jsonify({code: SUCCESS, message: 回调接收成功})这个接口要做幂等处理同一个 taskId 多次回调只处理第一次。可以在数据库里加唯一索引或者用 Redis 做去重。另外回调接口要快速返回不要在里面做耗时操作否则 WCS 会认为回调失败而重试。4. 并发、顺序与异常任务下发最容易翻车的四个地方4.1 并发下发导致任务乱序高峰期 WMS 可能同时下发几百条任务如果多线程并发发送WCS 接收顺序可能和 WMS 生成顺序不一致。对于有先后依赖的任务比如先出库再搬运乱序会导致死锁。解决办法在 WMS 侧对同一出库单的任务加锁按顺序逐条发送或者给任务加 sequence 字段WCS 侧按 sequence 排序后再执行。我一般会在任务模型里加一个sequence字段WCS 收到后先入优先队列按 sequence 排序。4.2 任务重复下发网络抖动导致 WMS 重试WCS 可能收到两条相同的 taskId。如果 WCS 不做去重就会执行两次货可能被搬两次。WCS 侧必须对 taskId 做唯一性校验收到重复 taskId 直接返回“已接收”。WMS 侧也要在发送前检查任务状态只有 CREATED 状态的任务才允许发送。4.3 状态回传丢失WCS 回调 WMS 时如果 WMS 服务重启或网络不通回调就丢了。任务状态会一直卡在 EXECUTING。兜底方案WMS 加一个定时任务每隔一段时间扫描超过预期时间仍未完成的任务主动去 WCS 查状态。WCS 需要提供一个查询接口根据 taskId 返回当前状态。4.4 位置编码不一致WMS 和 WCS 各自维护一套位置编码如果没对齐任务下发后 WCS 找不到起点或终点直接报错。血泪经验项目初期就要和 WCS 厂商交换位置字典最好用同一套编码规则。如果实在无法统一在 WMS 侧加一层映射表发送前把 WMS 位置编码转成 WCS 位置编码。5. 避坑与排查任务下发失败的五个典型场景5.1 现象WCS 返回“位置不存在”但 WMS 里位置明明有原因WMS 的位置编码和 WCS 的位置字典不一致或者 WCS 的位置字典没同步更新。解决先查 WCS 的位置字典接口确认目标位置是否存在如果不存在让 WCS 厂商同步如果存在但编码不同在 WMS 侧加映射。5.2 现象任务发送成功但 WCS 一直不执行原因任务优先级太低被其他任务堵住了或者 WCS 内部队列满了。解决查 WCS 的任务队列状态确认是否有积压如果是优先级问题调高 priority 值如果是队列满联系 WCS 厂商扩容。5.3 现象WMS 显示任务完成但实际货没到原因WCS 回调了 COMPLETED但设备实际没执行到位可能是传感器误报。解决WMS 不能完全信任 WCS 的回调关键节点要有二次确认比如打包台扫码确认收货。另外WCS 侧要有设备状态监控异常时主动上报。5.4 现象任务下发超时重试后 WCS 收到两条原因第一次请求其实成功了但 WMS 超时没收到响应重试导致重复。解决WCS 侧必须做 taskId 去重WMS 侧超时后不要立即重试先查一次任务状态确认没成功再重试。5.5 现象高峰期任务下发越来越慢原因WMS 同步发送任务每条都等 WCS 响应线程池被占满。解决改成异步发送WMS 把任务丢进内部队列后台线程池消费或者用消息队列解耦。同时给 WCS 接口加限流防止打爆。6. 让任务下发更稳的一个技巧用本地消息表做最终一致任务下发最怕的是“WMS 以为发了WCS 没收到”或者“WCS 收到了WMS 不知道”。要解决这个问题我一般会在 WMS 侧加一张本地消息表把“待发送”的任务先落库再异步发送发送成功后更新消息状态。这样即使服务重启也能从消息表里恢复未发送的任务。具体做法创建wcs_task_message表字段包括id, task_id, task_content, status (PENDING/SENT/FAILED), retry_count, create_time, update_time。业务代码在创建任务时同时插入一条 PENDING 消息。后台定时任务扫描 PENDING 消息发送给 WCS成功后更新为 SENT失败则重试并累加 retry_count。如果 retry_count 超过阈值比如 5 次标记为 FAILED触发告警人工介入。这个方案的好处是任务下发和业务操作在同一个本地事务里不会丢发送失败可重试状态可追溯。缺点是增加了一张表和定时任务但相比任务丢失导致的停线这点成本完全值得。验证方法可以手动把 WCS 接口停掉观察 WMS 是否会把消息标记为 FAILED 并告警恢复接口后看消息是否自动重发成功。这个测试我每次上线前都会做一遍能提前发现很多配置问题。最后说一个我自己的习惯每次对接新的 WCS 厂商我都会先写一个最小化的测试脚本只发一条任务把请求和响应完整打印出来确认字段、编码、状态都对了再批量发送。这个习惯帮我省了至少三次通宵排查。希望帮到你。本文还有配套的精品资源点击获取