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

  公司项目,项目要求是在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. 菜鸟学习Hibernate——持久层框架

    一.Java操作数据库的阶段. Java对数据库进行操作经历了三个阶段. 1.1操作JDBC阶段 这个阶段就是利用JDBC类来操作数据库.这个阶段出现了两个问题: 代码过度重复:在每一次数据库操作的是 ...

  2. Linux内核学习笔记——VFS

    概念: ①硬链接:若一个 inode 号对应多个文件名,则称这些文件为硬链接.即硬链接就是同一个文件使用了多个别名.硬链接可由命令 link 或 ln 创建. 其特性: 文件有相同的 inode 及 ...

  3. c语言中通过指针将数值赋值到制定内存地址

    1.一种直观的方法 假设现在需要往内存0x12ff7c地址上存入一个整型数0x100.我们怎么才能做到呢? 我们知道可以通过一个指针向其指向的内存地址写入数据,那么这里的内存地址0x12ff7c其本质 ...

  4. hdu 1023 Train Problem II

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1212 Train Problem II Description As we all know the ...

  5. PHP(一)

    最近一段时间一直忙于新版本的开发工作,所以虽然自己脑中有一些想法,但是苦于没有足够的时间去写下来.好了,昨天终于将大体的功能开发完成,时间上面也不会那么的紧张了.下来我想要好好的梳理一下,自己最近一段 ...

  6. Eclipse基金会

    昨天Eclipse基金会庆祝其成立十周年.2004年2月的新闻稿宣布该非盈利组织的正式成立,由包括开发者.消费者和插件提供商在内的各独立团体组成的董事会,为Eclipse的长期发展负责. 基金会成立时 ...

  7. Linux 编辑器

    vim编辑器 vi作为Unix上的一个编辑器,一直广受欢迎.之后GUN将其移植到开源世界中,经过开发人员对其进行了改善,被称为vi improved,就是现在的vim.为了方便使用,几乎所有的Linu ...

  8. ajax 例子

    引用 function initCsvModel(year,cityId){ var args = new Object(); args.url= "listUpload!initCsvMo ...

  9. 关于使用regsvr32命令注册ActiveX控件失败的解决办法

    昨天小编也遇到这样问题,步骤一切都对,没有错误,但是每次在命令行下输入的时候,都会弹出一个对话框: 最后我发现是存放ActiveX控件的路径中带有中文文件名字所导致,所以导致的错误,我们将所在路径下的 ...

  10. Machine Learning 学习笔记 (4) —— 广义线性模型

    本系列文章允许转载,转载请保留全文! [请先阅读][说明&总目录]http://www.cnblogs.com/tbcaaa8/p/4415055.html 1. 指数分布族简介 之前的文章分 ...