You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
4.1 KiB
143 lines
4.1 KiB
4 years ago
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using System.Runtime.Serialization;
|
||
|
using System.ServiceModel;
|
||
|
using System.Text;
|
||
|
using QMAPP.FJC.Entity.Basic;
|
||
|
using OpcHost.Init;
|
||
|
|
||
|
namespace OpcHost
|
||
|
{
|
||
|
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“PLCService”。
|
||
|
// InstanceContextMode.PerSession 服务器为每个客户会话创建一个新的上下文对象。ConcurrencyMode.Multiple 异步的多线程实例
|
||
|
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Multiple)]
|
||
|
public class PLCService : IPLCService
|
||
|
{
|
||
|
|
||
|
private static Object syncObj = new Object();////定义一个静态对象用于线程部份代码块的锁定,用于lock操作
|
||
|
IChatCallback callback = null;
|
||
|
private string machineNo;
|
||
|
|
||
|
#region IPLCService 成员
|
||
|
|
||
|
/// <summary>
|
||
|
/// 工控机向opcserver注册双通道通信
|
||
|
/// </summary>
|
||
|
public int Register()
|
||
|
{
|
||
|
|
||
|
//建立双通道通信
|
||
|
lock (syncObj)//线程的同步性,同步访问多个线程的任何变量,利用lock(独占锁),确保数据访问的唯一性。
|
||
|
{
|
||
|
if (string.IsNullOrEmpty(machineNo) == false && !ChatEventHelper.chatters.ContainsKey(machineNo))
|
||
|
{
|
||
|
ChatEventHelper.chatters.Add(machineNo, ReturnProductCode);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// 工控机向opcserver注销双通道通信
|
||
|
/// </summary>
|
||
|
public int Logout()
|
||
|
{
|
||
|
//关闭双通道通信
|
||
|
|
||
|
//关闭对应的线程。
|
||
|
|
||
|
if (this.machineNo == null)
|
||
|
return 0;
|
||
|
|
||
|
lock (syncObj)
|
||
|
{
|
||
|
ChatEventHelper.chatters.Remove(this.machineNo);
|
||
|
}
|
||
|
|
||
|
this.machineNo = null;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// 对工控机端执行的接口进行封装,
|
||
|
/// </summary>
|
||
|
/// <param name="sender"></param>
|
||
|
/// <param name="e"></param>
|
||
|
public void ReturnProductCode(object sender, ChatEventArgs e)
|
||
|
{
|
||
|
callback.ReturnProductCode(e.message);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// 返回工控机端产品条码信息
|
||
|
/// </summary>
|
||
|
/// <param name="productCode">产品条码</param>
|
||
|
/// <param name="machineNo"></param>
|
||
|
public void ReturnProductCodeToMachine(string productCode, string machineNo)
|
||
|
{
|
||
|
|
||
|
|
||
|
ChatEventArgs e = new ChatEventArgs();
|
||
|
e.message = productCode;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
|
||
|
ChatEventHelper.ChatEventHandler chatEvent;
|
||
|
lock (syncObj)
|
||
|
{
|
||
|
//通过工控机名称获取事件信息
|
||
|
chatEvent = ChatEventHelper.chatters[machineNo]; ; //查找成员字典中,找到要接收者的委托调用
|
||
|
}
|
||
|
|
||
|
//向工控机发送条码信息
|
||
|
chatEvent.BeginInvoke(this, e, new AsyncCallback(EndAsync), null);//异步方式调用接收者的委托调用
|
||
|
}
|
||
|
catch (KeyNotFoundException)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/// <summary>
|
||
|
/// 向设备发送可以进行操作的指令
|
||
|
/// </summary>
|
||
|
/// <param name="config"></param>
|
||
|
public void SendOperateOrder(ParameterConfig config)
|
||
|
{
|
||
|
|
||
|
ParaInit.SendOperateReadyOrder(config);
|
||
|
}
|
||
|
|
||
|
private void EndAsync(IAsyncResult ar)
|
||
|
{
|
||
|
ChatEventHelper.ChatEventHandler d = null;
|
||
|
|
||
|
try
|
||
|
{
|
||
|
//封装异步委托上的异步操作结果
|
||
|
System.Runtime.Remoting.Messaging.AsyncResult asres = (System.Runtime.Remoting.Messaging.AsyncResult)ar;
|
||
|
d = ((ChatEventHelper.ChatEventHandler)asres.AsyncDelegate);
|
||
|
d.EndInvoke(ar);
|
||
|
}
|
||
|
catch
|
||
|
{
|
||
|
//ChatEvent -= d;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|