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

  公司项目,项目要求是在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. 北京汽车官网经销商信息抓取(解析html标签)

    1.网站地址http://www.baicmotor.com/dealer.php 2.使用firefox查看后发现,此网站的信息未使用json数据,而是简单那的html页面而已 3.使用pyquer ...

  2. python Django 学习笔记(三)—— 模版的使用

    模版基本介绍 模板是一个文本,用于分离文档的表现形式和内容. 模板定义了占位符以及各种用于规范文档该如何显示的各部分基本逻辑(模板标签). 模板通常用于产生HTML,但是Django的模板也能产生任何 ...

  3. angularjs2 学习笔记(六) Form

    Angular 2 Form表单 在angular2 form表单中我们需要了解表单数据绑定.数据验证.数据提交等内容,在下面的示例中并没有实际提交到后台,这部分内容在今后webapi中加以练习. 表 ...

  4. Swing基础

    Swing基础 JFrame JPanel 绘图:paint 监听事件: ActionListener  KeyListener Listener和Adapter 计时器:Timer     Time ...

  5. android开发遇到SDK无法访问谷歌而安装不了的情况

    遇到SDK无法访问谷歌而安装不了的情况 1.修改C:\Windows\System32\drivers\etc的HOSTS文件,添加 #google_android更新203.208.46.146 d ...

  6. JavaScript AJAX stream 流式显示

      当使用AJAX进行信息交互的时候,如果服务器返回的信息比较大,那么相对于传送完成之后的统一显示,流式显示就比较友好了. 流式实现 原理就是设置定时器,定时的查看AJAX对象的状态并更新内容,如果传 ...

  7. iOS学习之C语言函数指针

    通过函数名调用函数: int max = maxValue(4, 5); printf("max = %d\n", max);     函数类型:int (int, int) 1. ...

  8. jquery.form的使用

    插件API http://malsup.com/jquery/form/#api Jquery.form.js是支持文件异步上传的插件,jq插件自然基本前提当然是要引用Jquery.js 1.0 基本 ...

  9. 条款2:尽量以const、enum、inline替换#define

    1> 以const替换#define • 比如用const double Ratio = 1.653替换#define RATIO 1.653 因为宏定义在预处理阶段就会被替换成其所指代的内容, ...

  10. Qt 读取txt文件乱码的解决办法

    Qt 读取txt文本乱码问题 2015-05-20 15:46 方法一:使用QString的fromLocal8Bit()函数 复制代码 QFile txtfile(filePath);        ...