Giocando con l'interoperabilità (parte 3)

Ecco qui la terza, forse non ultima, parte di "Giocando con l'interoperabilità". Qui la prima parte e qui la seconda., da leggere se volete capire bene questa parte.

In questo articolo tratteremo i componenti _radio_, pubblicherò il codice di quello in C# e di uno in java (si proprio qllo della Sun)... un ip-ip-urrà per xml e l'interoperabilità :-p

Radio

La radio ha il compito di mettersi in ascolto sul canale multicast, riceve e mostrare i messaggi pubblicati dal BroadcastingStudio, qui descritto. Il progetto sarà - come mio solito - una bella console application in cui includerò le classi generate usando il solito schema xsd, qui descritto. Inoltre includeremo nella nostro programma una classe di utilità per ricevere i dati dal multicast. La classe UdpClient ha qualche problema nel fare questo, come qui avevo detto, e per questo implemento la seguente classe.

using System;
using System.Net;
using System.Net.Sockets;
namespace Radio
{
 public class UdpHelper
 {
  class MulticastUdpClient: UdpClient
  {
   public MulticastUdpClient(IPEndPoint ipEndPoint)
   {
    //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/setsockopt_2.asp
    //SO_REUSEADDR (BOOL) Allows the socket to be bound to an address that is already in use.  
    Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);        
    Client.Bind(new IPEndPoint(IPAddress.Any, ipEndPoint.Port));
    JoinMulticastGroup(ipEndPoint.Address);   
   }
  }

  /// 
  /// Crea udp client per riceve messaggi da gruppo multicast.
  /// 
  public static UdpClient CreateMulticastGroupClient(IPEndPoint ipEndPoint)
  {   
   return new MulticastUdpClient(ipEndPoint);
  }
 }
}

Ecco quindi la nostra _Radio_.

using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace Radio
{
 class Program
 {
  [STAThread]
  static void Main(string[] args)
  {
   try
   {
    //configurazione ...
    IPAddress addressGroup = IPAddress.Parse("234.5.5.1"); 
    int groupPort = 5555;
    IPEndPoint endPoint = new IPEndPoint(addressGroup, groupPort);
    //creo multicastSocket ...
    UdpClient udp = UdpHelper.CreateMulticastGroupClient(endPoint);
    Console.WriteLine("listening ...");
    while(true)
    {
     //ricevo i datagram pubblicati ...
     IPEndPoint endPointRef = null;
     byte[] bytes = udp.Receive(ref endPointRef);
     //deserializzo e stampo a video ...
     XmlSerializer ser = new XmlSerializer(typeof(message));
     message messageReceived = (message) ser.Deserialize(new MemoryStream(bytes));
    
     Console.WriteLine(messageReceived.text);
     foreach(messageTrackingStage trackingStage in messageReceived.tracking)
     {
      Console.WriteLine("{0:dd/MM/yyyy HH:mm:ss} - {1}", 
       trackingStage.date, 
       trackingStage.Value);
     }     
    }
    
    //Qui dovrei rilasciare il gruppo ma il ciclo di lettura è infinito.
    //Warning di compilazione: "Unreachable code detected";
    //udp.DropMulticastGroup(addressGroup);
   }
   catch(Exception e)
   {
    Console.WriteLine(e);
    Console.ReadLine();
   }   
  }
 }
}

JRadio

Ecco ora la stessa _Radio_, realizzata in java. Ogni volta che riprendo java mi stupisco di quanto il linguaggio voglia raggiungere livelli di astrazione sempre più spinti al punto da rendere il linguaggio quasi ostico. E pensare che fu geniale per aver unito, forse per primo, semplicità e potenza... ma sta - amio avviso - pian piano cadendo chiuso nella voglia di disegnare l'utpoiko _mondo perfetto_ e sordo nel sentire le esigenze della necessità di essere produttivi. Nel codice mi son messo un bel TODO per un approfondimento, spero di scoprire qualcosa di positivo che magari mi possa far ricredere... anche se la formattazione del messaggio e il parsing della data la dicono lunga :-p

package MarcoBarzaghi.Demo;
import java.net.*;
import java.util.*;
import java.text.*;
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
public class JRadio 
{
 
 public static void main(String[] argv) throws IOException
 {
    
  try
  {
   //configurazione ...
   InetAddress address = InetAddress.getByName( "234.5.5.1" );
   int port = 5555;  
   int bufferSize = 1024;
   //creo multicastSocket ...
   MulticastSocket socket = new MulticastSocket( port );
   socket.joinGroup( address );
   System.out.println("listening ...");
   while(true)
   {
    //ricevo i datagram pubblicati ...
    byte[] buffer = new byte[bufferSize];
    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    socket.receive(packet);
    
    //leggo e stampo a video xml ...
 
    //TODO: vedere serializzazione Xml e "XML Class Generator", 
    //http://www.oracle.com/technology/sample_code/tech/xml/productorders/Readme.html 
 
    ByteArrayInputStream inputStream = new ByteArrayInputStream(packet.getData(), packet.getOffset(), packet.getLength());
    Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream);
     
    String text = document.getElementsByTagName("text").item(0).getChildNodes().item(0).getNodeValue();
    System.out.println(text);
 
    NodeList trackingStageNodeList = document.getElementsByTagName("stage");
    int count = trackingStageNodeList.getLength();
    for(int i = 0; i < count; i++)
    {
     Node trackingStageNode = trackingStageNodeList.item(i);
     String stageText = trackingStageNode.getChildNodes().item(0).getNodeValue();    
  
     String stageDateText = trackingStageNode.getAttributes().getNamedItem("date").getNodeValue();        
     Date stageDate = (new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")).parse(stageDateText, new ParsePosition(0)); 
  
     MessageFormat messageFormat = new MessageFormat("{0,date,dd/MM/yyyy HH:mm:ss} - {1}");
     Object[] messageArguments = {stageDate, stageText};               
     System.out.println(messageFormat.format(messageArguments));
    }
   }  
   //qui dovrei rilasciare il gruppo ma il ciclo di lettura è 
   //infinito. Errore di compilazione: "unreachable code" :-p
   //socket.leaveGroup(address);     
  }catch(Exception e){   
   System.out.print(e.getMessage());
   e.printStackTrace(System.out);
   System.in.read();
  }
 }
}

Come per il BroadcastStudio, qui descritto, anche le radio non hanno la pretesa di essere user-friendly... per cui CTRL + C per spegnerle :-p

posted @ sabato 23 aprile 2005 01:50

Print
Comments have been closed on this topic.
«aprile»
domlunmarmergiovensab
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011