许久不曾写随笔,即使许久的怠惰,是该抬抬头,看看天了。

  公司项目,项目要求是在winForm端先获取下位机的肌电信号采集数据,然后根据这些数据的变化来控制flash游戏,这样一些患者在flash游戏中达到肢体训练的效果。

  在这里 需要用到c#与flash的通信, 先上通信示例

ActionScript3.0 与ActionScript2.0 略有差异,但和C#的通信方式是不变的。

function xmlToArray(list:XML):Array {
//xml转数组
list.ignoreWhite = true;
var ar:Array = new Array();
var list_node:XMLNode = list.firstChild.childNodes[];
var l:Number = list_node.childNodes.length;
for (var i:Number = ; i<l; i++) {
var node:XMLNode = list_node.childNodes[i];
var ob = new Array();
ob.push(node.childNodes[].childNodes[].nodeValue);
ob.push(node.childNodes[].childNodes[].nodeValue);
ar.push(ob);
}
return ar;
} ExternalInterface.addCallback("onPlatformMessage",null,onPlatformMessage);
var xmlContent:XML;
var messageName:String, messageType:String, gameId:String;
function onPlatformMessage(args:String) {
xmlContent = new XML(args);
list_arr = xmlToArray(xmlContent);
//fscommand('Message', '<Message name="GAME_SCORE_REPLY" type="2" gameId="4025"><PlayerScore>'+list_arr+'</PlayerScore></Message>');
messageName = xmlContent.firstChild.attributes.name;
messageType = xmlContent.firstChild.attributes.type;
gameId = xmlContent.firstChild.attributes.gameId;
if (messageType == '' && gameId == '') {
switch (messageName) {
case 'GAME_VERSION' :
fscommand('Message', '<Message name="GAME_VERSION_REPLY" type="2" gameId="4025"><GameVersion>1.0</GameVersion></Message>');
break;
case 'PLAYER_ENTER' :
if (gameFinished) {
playerMode = xmlContent.childNodes[].childNodes[].childNodes[].nodeValue;
if (playerMode != ) {
//playerMode=xmlContent.PlayerMode;
playerName = xmlContent.childNodes[].childNodes[].childNodes[].childNodes[].nodeValue;
level = xmlContent.childNodes[].childNodes[].childNodes[].nodeValue;
score = xmlContent.childNodes[].childNodes[].childNodes[].childNodes[].nodeValue;
if(level>)(level=);
gotoAndStop();
fscommand('Message', '<Message name="GAME_ENTER_OK" type="2" gameId="4025"></Message>');
}
}
break;
case 'GAME_PAUSE' :
if (!gameFinished) {
pauseGame(true); }
break;
case 'GAME_RESUME' :
if (!gameFinished) {
continueGame(); }
break;
case 'GAME_LEAVE' :
gameFinished = true;
fscommand('Message', '<Message name="GAME_LEAVE_OK" type="2" gameId="4025"><PlayerScore>'+score+'</PlayerScore><GameStage>'+level+'</GameStage></Message>');
break;
case 'GAME_HELP' :
break;
case 'GAME_SOUND' :
break;
case 'GET_GAME_SCORE' :
fscommand('Message', '<Message name="GAME_SCORE_REPLY" type="2" gameId="4025"><PlayerScore>'+score+'</PlayerScore></Message>');
break;
case 'GET_GAME_STAGE' :
fscommand('Message', '<Message name="GAME_STAGE_REPLY" type="2" gameId="4025"><GameStage>'+level+'</GameStage></Message>');
break;
case 'SET_GAME_STAGE' :
if (!gameFinished) {
level = xmlContent.childNodes[].childNodes[].childNodes[].nodeValue;
gotoAndPlay();
fscommand('Message', '<Message name="SET_GAME_STAGE_OK" type="2" gameId="4025"></Message>');
}
break;
case 'GET_GAME_STATUS' :
//tmpInt = xmlContent.firstChild.attributes.GameStage;
fscommand('Message', '<Message name="GAME_STATUS_REPLY" type="2" gameId="4025"><GameStatus>'+gameStatus+'</GameStatus></Message>');
break;
case 'SET_LANGUAGE' :
var language = xmlContent.firstChild.attributes.GameLanguage;
break;
default :
searchHighscore();
}
}
//end if
}
//end onPlatformMessage

Flash端的ActionScript2.0代码

如上示例:

Flash接收c#消息方式:

  ExternalInterface.addCallback("onPlatformMessage",null,onPlatformMessage);

  引号中的onPlatformMessage是flash用于接收c#消息的方法名

  后面的onPlatformMessage 是接收到的c#传递的参数,该参数可以有一个或多个(本项目中只用到一个参数)。

  然后再onPlatformMessage方法中,AS(ActionScript)会先把c#传递过来的额XML的字符串进行解析,解析之后就可以执行flash的相应动作。

Flash回复c#消息

  fscommand('Message', '<Message name="SET_GAME_STAGE_OK" type="2" gameId="4025"></Message>');

C#端的操作

  C#端使用的是WinForm形式。

准备工作:

  首先添加对 COM 组件 Shockwave Flash Object 的引用,将该组件拖到窗体上之后,可以设置如下关键属性:

    Movie: Flash 的存放地址
    EmbedMovie: 是否嵌入到程序的资源中。

  或者在程序中把flash加载进去:

player.LoadMovie(0, Application.StartupPath + "\\EITest.swf");

// player.Play();

在使用player.Play()中遇到的问题是:

  在c#与ActionScript2.0 通信中在Load使用使用Play() 命令可以使用flash正常播放,但在c#与ActionScript3.0 的通信中却遇到了错误。后来查找原因大概是在执行 player.LoadMovie() 的时候是把flash加载进来,player.Play() 会自动播放flash,相当于在ActionScript语法中执行了play方法,这样会与flash中原来的方法造成冲突,最后是没有使用后一步的player.Play()方法。

C# 接收flash的消息:

private void player_FSCommand(object sender, AxShockwaveFlashObjects._IShockwaveFlashEvents_FSCommandEvent e)
{
if (e.command == "Message")
{
lblreceive.Text = e.args;
//游戏载入时,发送参与人的编号和姓名
if (e.args.IndexOf("GAME_LOAD_OK") != -)
{
messageName = "PLAYER_LOAD";
LoadPlayer();
}
}
}

c#接收flash消息

  上面的player是与flash通信的客户端的ID,在winForm中注册player的FSCommand的方法,此方法的作用即时在主线程中不停地刷新来接收flash发送给c#的消息。

  其中e.command 是flash中 fscommand函数的第一个参数

  e.args是flash中 fscommand函数的第二个参数

c#发送给flash的消息

private void Command_SetSpeed(int speed)
{
messageName = "Action_Speed";
player.CallFunction("<invoke name=\"onPlatformMessage\" returntype=\"xml\"><arguments><string>" +
" <Message name=\"" + messageName + "\" type=\"1\" gameId=\"" + gameId + "\"><Speed>" + speed.ToString() + "</Speed></Message>" +
"</string></arguments></invoke>");
}

c#接收flash消息

  在c#中使用player.CallFunction()方法向flash发送消息,其中"onPlatformMessage"是flash接收消息的方法名。

在本项目中,向flash发送的消息,只有<string>标签中的消息不用,其他的格式都是通用的。

通信原理及过程:

  通信原理个人不甚懂,摘抄他人的解释共享。

其基本过程为:flash中注册函数——将要调用的函数名、参数等信息打包为xml—>将xml传递到flash中执行调用—>执行ActionScript函数—>flash自动将结果打包为xml—>将结果xml传递回C# —>C#解析xml得到返回值

可见,flash与C#通信是通过特定格式的xml文件进行的,因此为了实现通信,C#必须实现一下功能:识别该xml格式以得到flash发送来的信心,将需要传送给flash的信息打包成flash能识别的xml格式。为了使用方便我们可以设计一个代理类专门负责数据的解析与打包工作,这样我们就可以透明的使用该代理类来实现flash与C#间的互相调用。

在flash的示例中有一个IntrovertIM_CSharp项目较好的实现了代理的编写,一般情况下,使用该示例中的ExternalInterfaceProxy类足以满足要求,因此方便起见我也直接采用了该代理类。

该类的使用非常简单,通过将flash控件作为参数传递给该类的构造函数,我们就可以建立一个给控件的代理,简单的响应代理的ExternalInterfaceCall事件及使用代理类的Call()方法就能实现与flash通信,中间的数据转换工作完全由代理透明的实现,用户无需关心。

其它语言及程序课根据上面原理编写自己的代理类来实现数据的解析与打包工作。

c# 与flash通信简介的更多相关文章

  1. Javascript与Flash通信全解析

    原文:https://www.imququ.com/post/39.html Flash已经提供了ExternalInterface接口与JavaScript通信,ExternalInterface有 ...

  2. Flash Memory 简介【转】

    本文转载自:https://linux.codingbelief.com/zh/storage/emmc/ Flash Memory 是一种非易失性的存储器.在嵌入式系统中通常用于存放系统.应用和数据 ...

  3. socket通信简介

    转:http://blog.csdn.net/xiaoweige207/article/details/6211577 “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的 ...

  4. NAND Flash内部结构简介

    介绍     1965年,在双极管被W.Shockley.W.Brattain和J.Bardeen三人发明出来之后,Intel的合作创始人Gordon Moore发现了这样一条法则:当价格不变时,集成 ...

  5. 转:socket通信简介

    转:http://blog.csdn.net/xiaoweige207/article/details/6211577/ 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页 ...

  6. dubbo结构及通信简介

    一.导论 dubbo作为阿里开发优秀的rpc服务框架,现已广泛用于各大rpc项目之间的远程通信,虽然阿里现在已经没有维护dubbo的开发,但是其结构设计也是值得学习. 二.结构简介 这部分只是简单介绍 ...

  7. ROM、PROM、EPROM、EEPROM、FLASH ROM简介

    ROM指的是"只读存储器",即Read-Only Memory.这是一种线路最简单半导体电路,通过掩模工艺, 一次性制造,其中的代码与数据将永久保存(除非坏掉),不能进行修改.这玩 ...

  8. [转]UART通信简介

    1.前言 UART通信,即通用异步收发传输器(Universal Asynchronous Receiver/Transmitter). 串行通信是指利用一条传输线将资料一位位地顺序传送.特点是通信线 ...

  9. 【转】socket 通信简介

    转自:http://blog.csdn.net/xiaoweige207/article/details/6211577/ “一切皆Socket!” 话虽些许夸张,但是事实也是,现在的网络编程几乎都是 ...

随机推荐

  1. 配置visual studio code进行asp.net core rc2的开发(转载jeffreywu)

    1.安装.net core sdk https://github.com/dotnet/cli#installers-and-binaries,根据你的系统选择下载 2.下载vscode的C#扩展插件 ...

  2. jquery mobile最棘手的一个问题

    大多数jquery mobile开发的妹子们都碰到过这个问题: 如何调用loading效果   这里给出一段代码,赶紧练手吧. //显示loading function showLoading(){ ...

  3. Objective-C关于分类、扮演、协议

    -----<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培 ...

  4. 做HDU1010 带出来一个小问题

    做1010  本来是想的DFS深搜  但是自己凭空打  打不出来  因为没有记模板  然后就去搜  但是看了一遍  自己打却又是有BUG  然后验证  就出现了一个二维字符数组打印的问题 开始代码是这 ...

  5. mysql外键设置(待测试)

    外键的定义语法:[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)    REFERENCES tbl_name (index_col ...

  6. Binder相关

    Binder分析 需了解C/S还有管理这些的ServiceManager. 简单来讲你(client)有个包裹(parcel)让快递员(proxy)送到公司(server),   公司(server) ...

  7. scjp考试准备 - 3 - 关于Arrays

    判断如下程序的最终输出值: import java.util.*; public class Quest{ public static void main(String[] args){ String ...

  8. 代码实现Autolayout

    代码实现Autolayout的步骤 利用NSLayoutConstraint类创建具体的约束对象 添加约束对象到相应的view上 - (void)addConstraint:(NSLayoutCons ...

  9. android selector

    android 选择器的使用 1.在drawable文件夹下面建一个xml文件,如item.xml,在eclipse中有selector这个选项 2.可以在布局文件.xml(配置android:lis ...

  10. Java多线程时内存模型

    1. 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标之一.一般衡量一个服务器性能的高低好坏,使用每秒事务处理数(Transactions Per Second,TPS)这个指标比较能说明问题 ...