Month: October 2021

Humble Software Bundle: Learn Unity Game Development (uma campanha)

Está a decorrer uma nova campanha relacionada com cursos acerca do Unity, e da lista consta:
Unity Multiplayer Course: Intermediate C# Coding & Networking
Unity Mobile C# Developer Course
Complete C# Unity Game Developer 2D Course
Complete C# Unity Game Developer 3D Course
Game Dev Skill Builder (Unity) – Season 2
Ultimate Music Bundle by Sidearm Studios
Ultimate SFX Bundle by Sidearm Studios
Programming Patterns Introduction Course
Data Oriented Tech Stack Introduction Course
Game Dev Skill Builder (Unity) – Season 1
RPG 2D Art Asset Pack
Get Git Smart Course: Learn Git in Unity, SourceTree, GitHub
Unity UIToolkit for Editor Scripting Introduction Course

+infos(oficial): LINK

Tags : , , , , , , ,

Propostas de trabalho (em Gaia)

+infos(oficial): https://saber3d.com/

 

Tags : ,

PAM, Plastic Army Men

Há muito tempo que não ouvia falar destes bonecos de plástico verdes, militares e em alguns casos também existiam veículos. Tantas horas que brinquei sozinho e com um amigo com estes bonecos.
Encontrei alguém que se deu ao trabalho de construir um plano para se jogar com estes bonecos. Basta ter os bonecos e construir um cenário  :)
É um projeto interessante :)

Não sou fã das versões em grande, gostei sempre das versões mais pequenas dos bonecos, sempre eram “mais realistas” para estarem juntos dos veículos.

+infos(livro): https://payhip.com/b/Ksl54

+infos(rede social): LINK

Tags :

Propostas de trabalho (no Porto)

A FABAMAQ tem em aberto várias propostas de trabalho:

SOFTWARE DEVELOPER – GAME DEVELOPMENT
Responsibilities:
– You will use your Software Development skills on our Game Development context, a fast pace development environment will be waiting for your contribution.
– From design to hands on implementation of our game features, you will work, interact and develop games along with Graphic Artists, Sound Designers, work closely with Game Testers. An agile coach will help and push you on this journey and a Product owner will work closely with our clients in order to give your team the knowledge you need to build successful games.
– Your contribution will add value to a code base that has shipped multiple products and that needs constant innovation, demands you to be eager to learn as well to question it along the way in order to improve its capability to fulfill our client’s needs.
– You will be developing games, with focus on quality, performance and reliability, so along the way your problem solving skills will be needed not only to create new features but also to solve detected bugs and improve our software health.
– We expect you to be Self-driven and excel at completing tasks in a minimally supervised environment.
Expected:
– Degree in Computer Science, related field or equivalent experience
– Good knowledge of Software Architecture and Software Patterns.
– Good Analytical, and problem solving skills.
– Experience coding in C++.
– Knowledge of Javascript fundamentals.
– Full software life-cycle application development – designing, coding, debugging, testing and documenting applications.
– Being a good team player, able to deal with different ways of working and thinking.
– Proactive mindset to fix bugs.

Digital Game Development
Responsibilities:
Development and maintenance of software related to the provision and integration of online games (fortune and chance);
Expected:
– Either/Both a degree in Computer Science (or similar area) or proven experience in software development;
– Two years of professional experience in software development or similar position;
– Proficiency in Python 2.7+ and Python 3.8+;
– Familiarity with Git;
– Competence in Unix.

Godot Game Development
Responsibilities:
– Development and maintenance of software related to Godot Engine;
– Development and maintenance of our web-based game engine for casino games (slots, bingo, poker, etc);
– Supporting the development of tools to bridge the design team work with our engine.
Expected:
– Proficiency with development in Godot Game Engine;
– Either/Both a degree in Computer Science (or similar area) or proven experience in software development;
– Familiarity with Git and Python.

+infos(oficial): https://www.fabamaq.com/

Tags : ,

Uma campanha pela malta da Unity Store..

A Unity Store volta e meia tem uma campanha a decorrer. Neste momento tem uma com algumas coisas interessantes. A lista é:
RPG Monster Wave Polyart
New Textures & Standard Pipeline Conversion for Book of the Dead
Animal pack deluxe
Cartoon FX Remaster
Easy Trail Effect (URP & LWRP)
Lean Touch+
Magic Arsenal
2D Pixel Unit Maker – SPUM
Polygon Arsenal
The Illustrated Nature
Character Controller Pro
ArchVizPRO Interior Vol.2
Puppet Face
Mountain Trees – Dynamic Nature
Emerald AI 3.0
Animal Controller
Dreamteck Splines
Ultimate Game Music Collection
Survival Engine – Crafting, Building, Farming
Aura 2 – Volumetric Lighting & Fog
Master Audio: AAA Sound
Toon City
Enviro – Sky and Weather

+infos(a campanha): LINK

Tags : ,

Humble Software Bundle: Unity, FPS Games & Game Dev Assets (uma campanha)

Uma campanha na plataforma Humble.. com vários assets para serem usados no Unity no desenvolvimento do género FPS e dois jogos. Da lista de prendas desta campanha consta:
UFPS: Ultimate FPS
SCI FI CHARACTERS MEGA PACK VOL 2
Character Movement Fundamentals
Highlight Plus
Tannenberg – Steam Game
Verdun – Steam Game
Polarith AI Pro | Movement with 3D Sensors
Sensor Toolkit
Super Multiplayer Shooter Template
CScape City System
3D Scifi Kit Vol 3
Impact – Physics Interaction System
Animated Hands with Weapons Pack
Post Apocalyptic World Pack
ProTips – Tooltip System
RV Smart AI
RV Honor Ai
Gun & Explosion Sounds
Colossal Game Music Collection
GUI PRO Kit – Sci-Fi Survival
Sci-Fi Gun Sounds
Sci-fi Weapons Arsenal
Footstep and Foley Sounds
CITADEL: Desert Environment Pack
JU TPS 2 : Third Person Shooter System + Vehicle Physics
Shooting Range Interiors

+infos(a campanha): LINK

Tags : , , , , , , ,

resolução de exercícios

#exame 2019-2020 e #exame 2016-2017
Exame da Época Especial – Avaliação prática – P1

==teórica)
1. Diga, justificando, se é correcto afirmar-se que o seguinte método permite apenas copiar o conteúdo de um ficheiro para outro. Se a resposta for negativa, inclua na justificação pelo menos um contra-exemplo.
public static void copy(java.io.InputStream in, java.io.OutputStream out) throws java.io.IOException
{
int c;
while ((c = in.read()) != -1){
out.write(c);
}
}

R:
pode ser usado também para leitura e escrita em sockets
as classes InputStream e OutputStream são classes abstractas, e uma classe abstracta são aquelas em que existe pelo menos um método não implementado
neste exemplo temos um método que recebe dois métodos: InputStream e OutputStream
o InputStream é uma classe abstracta que tem métodos do tipo: read, read só com um caracter, receb arrays de bytes e devolve o numero de bytes copiados, e subarrays, ..
o OutputStream é uma classe abstracta que tem métodos do tipo: tem métodos para escrever, e que permite ir buscar bytes ou um fluxo de bytes, por exemplo no ecrã, num ficheiro, numa ligação TCP, pode ser um array de bytes,..

mas a resposta é não porque são classes abstractas
posso copiar de ficheiro para ficheiro
posso copiar de ficheiro para socket
posso copiar de socket para ficheiro

para teste:
o OutputStream só permite serializar para ficheiro? ou só permite serializar para socket?
r:
não porque ao criar um objecto OutputStream passamos-lhe qualquer coisa que é OutputStream
o que o wirte and share do OutputStream precisa de receber um objecto que implemente os métodos do OutputStream, e não interessa como

para teste:
o que faz o método write object no OutputStream
r:
o write object implementa o algortimo de serialização, pega num objecto, que na realidade é uma arvore de objecto (porque depois temos referências), e o que produz num formato especifico que é um binário java, produz um fluxo de bytes contiguos que permite desctever no objecto as várias classes envolvidas,as versões, os valores, os membros, .., e que permite depois ser transmitido ou guardar

para teste:
o que um driver, o que faz um driver jbdc?
R:
o driver é um conjunto de classes que vamos buscar num jar e que tem classes/métodos que implementam a api do jbdc
o driver é a implementação dessa API, dessas classes, para acesso a servidores de BD especificos

para teste:
R:
porque não posso usar um conector mysql para aceder a uma base de dados de oracle?
têm drivers diferentes, porque muitas das coisas que as classes/métodos fazem é estabelecer uma ligação TCP ao servidor remotamente
e enviar pedidos num determinado formato que tem a ver com o protocolo e os SGBD, e quem desenvolveu o protocolo não desenvolveu nenhum protocolo de comunicação ao nivel a aplicação, entre o cliente o servidor BD, não implemntou de forma standart e por esse motivo as mensagens e as trocas de mensagens são diferentes

==teórica)
2. Geralmente, associado a plataformas de middleware que oferecem a abstracção de objecto remoto/distribuído, existem aplicações que, em termos genéricos, podem ser designadas de serviços de nomeação (por exemplo, rmiregistry.exe, tnamrserv.exe e orbd.exe). Explique quais são os seus dois objectivos principais e de que forma estes são atingidos (ou seja, enumere as principais operações/passos executados desde a fase de arranque). Na resposta, que não deve incluir código, utilize, entre outros, os termos socket, mensagem, porto e thread.
r:
conceito de RMi (ou corba)
estas têm uma aplicação autónoma, mas que têm o mesmo objectivo e que são os serviços de nomeação
rmiregistry (no RMi)
orbd (no Corba)
o rmiregistry
os dois principais objectivos são:

ao inves de saber o ip e o porto automático do servidor, mas eu coloco numa maquina qualquer com o ip conhecido e com porto fixo de 1099,
assim
o servidor quando arranca contacta (ligação TCP) o rmiregistry
e envia uma informação a dizer regista este proxy/este serviço sob este nome
uma aplicação que quer aceder ao serviço contacta o rmiregistry (ligação TCP, no ip e no porto 1099) a pedir o serviço remoto
o rmiregistry faz o lookup e devolve serializado ou envia uma excepção.
a aplicação recebe, tem uma classe, recebe um objecto do tipo, onde tem o ip e o porto da maquina(servidor) onde está o serviço

r2:
dois objectivos:
registar serviços com um determinado nome, referências para objectos remotas sob determinados nomes, e permite obter essas referencias através de queries
e permite obter a referência, isto é, permite fazer um submit e um get
e enumere as principais fazes de arranque:
é um servidor TCP concorrente, que é posto a correr,
e quando quero utilizar o serviço faço uma ligação TCP com a indicação do porto, e é enviado um pedido sobre a forma de uma mensagem

o servidor está à espera de pedidos de ligação, e como é um servidor concorrente, sempre que alguém se liga cria uma thread, aguarda o pedido e responde
(lembrar que só existe uma forma de comunicar na internet, e é através de sockets)

para teste:
o que faz, qual o objectivo este método estático e o que é desencadeado quando o chamam:
Naming.bind(“rmi://192.168.1.1/nome1”, o);
objetivo: solicitar a uma aplicação rmi, que está a correr na maquina com o ip 192.168.1.1, com o porto 1099, e enviar-lhe o registo do serviço/referencia remoto o, com o nome nome1
estabelece um ligação TCP, e enviar-lhe uma mensagem, com o regista-me aí um serviço RMi com o nome nome1, e também toma a referência serializada o
se correr bem ele acrescenta
se correr mal ou se já existir ele lança uma excepção
e ele envia uma resposta (uma excepção ou um true ou um false)

para teste:
Naming.rebind(“rmi://192.168.1.1/nome1”, o);

para teste:
o que faz, qual o objectivo este método estático e o que é desencadeado quando o chamam:
Naming.lookup(“rmi://192.168.1.1/nome2″);
contactar uma aplicação Rmi registry que está no ip 192.168.1.1, na porta 1099, de qualquer coisa que ele tem com o nome nome2
estabelece um ligação TCP, no ip e no porto
constroi uma mensagem que obtem a referencia para o nome2
serializa a mensagem, através da ligação TCP
do outro lado o registry vai receber a mensagem, e verifca se corre bem, se encontra, e devolver o resultado
e quando se recebe a mensagem desserializa-a e vê a resposta, e com base na resposta devolve a referencia remota ou lança uma excepção

==teórica)
3.Diga qual é o objectivo do seguinte método e descreva o significado de cada um dos campos que compõem a URL passada como argumento (rmi, 192.168.1.1, 1099 e RMILightBulb):
java.rmi.Remote r = java.rmi.Naming.lookup(“rmi://192.168.1.1:1099/RMILightBulb”).
r:
o objecto é obter uma referencia remota para o objecto que está registado no rmiregistry com o nome RMILightBulb
rmi, é o protocolo usado na comunicação, é o que define as mensagens trocadas entre a aplicação que chama isto e a aplicação do outro lado
192.168.1.1, é o ip onde está a correr o rmiregistry
1099, é o porto onde está a correr o rmiregistry
RMILightBulb, é o nome do serviço

para teste:
o que é que acontece por baixo com java.rmi.Remote r = java.rmi.Naming.lookup(“rmi://192.168.1.1:1099/RMILightBulb”)?
r:
estabelece uma ligação TCP naqueles ip e porto, envia uma mensagem com um pedido para uma referência remota de um objecto que se chama RMILightBulb e aguarda resposta
se a resposta for um objecto do tipo excepção faz o throw da excepção
caso contrário faz o return do que recebeu e depois temos que fazer o cast

==teórica)
4. O pedaço de código seguinte permite obter um recurso alojado um servidor Web através do protocolo HTTP, recorrendo a uma classe específica que encapsula esse tipo de interacção. Sabendo que o HTTP é um protocolo do nível de aplicação que recorre ao protocolo de transporte TCP e, por imissão, ao porto 80, deduza a sequência de acções/passos principais desencadeados pelo método openStream (1- Estabelece… 2- … m- Envia… n- Obtém… o-
Devolve…). A resposta não deve incluir código.
java.net.URL myURL = new java.net.URL (“https://moodle.isec.pt/moodle/mod/folder/view.php?id=470″);
java.net.InputStream in = myURL.openStream();
int b;

while(true){
b = in.read();

}
r:
existe um objecto do tipo:
java.net.URL myURL
depois temos
java.net.InputStream in = myURL.openStream();
e de seguida:
b = in.read();
e com tudo isto estou a receber o conteudo da resposta get que foi enviado para este servidor e para este recursoview.php?id=470

o URL pode dar-me uma excepção
quando se faz o myURL.openStream(), e
estabelece uma ligação TCP nesta maquina (https://moodle.isec.pt/)
envia um pedido get oara identificar como recurso o URI: moodle/mod/folder/view.php?id=470
e do outro lado ele vai enviar uma resposta com várias linhas de texto com vários \n \n e fecha a ligação TCP
no buffer de entrada eu vou ter os bytes enviados, que é a resposta
fica associado ao objecto java.net.InputStream in = myURL.openStream();
e ao fazer o read b = in.read();
vão ser lidos os bytes

==teórica)
5. Acrescente uma única linha de código na classe UseMyThreads ou MyThread de modo a que a thread t2 apenas inicie depois de t1 deixar de estar activa. Altere igualmente a declaração do método metodo1 de modo a que, se várias threads possuírem uma referência para a mesma instância da classe MyThread, este apenas possa ser executado por uma única thread em cada instante.
public class MyThread extends Thread {
X x;
public MyThread(X x){
this.x = x;
}

public metodo1(){

}

public void run() {

}

}

public class UseMyThreads {

public static void main(String args[]){

Thread t1 = new MyThread(new X()).start();
Thread t2 = new MyThread(new X()).start();

}
}
r:
a Thread t1 = new MyThread(new X()).start();
vai correr o run

assim e no UseMyThreads podemos usar um JOIN
Thread t1 = new MyThread(new X()).start();
t1.join;

r2:
ou até podia olhar para:
assim e no MyThread e no run() podemos fazer
synhcronized(x){…};
mas quando fazermos new MyThread(new X()).start();
estamos a criar objectos novos e não vão bloquear logo esta solução não é válida só seria se
ao invés de:
Thread t1 = new MyThread(new X()).start();
Thread t2 = new MyThread(new X()).start();
e se existir:
declaração de um X = new X
e passar o X para dentro de cada thread este mesmo X
e agora sim vem o synhcronized do X
mas isto tb não é veridico face ao não sabes como vai ser o escalonamento e isso depende do SO

atenção: não é porque no código existe uma sequencia que u output é sempre igual.. as coisas variam face ao escalonamento

r3:
segunda parte da resposta é meter o método 1 como synhcronized
na classe MyThread
public synhcronized metodo1(){ … }
eu posso fazer synhcronized ao nivel do método no run nao posso só internamente

r4 final:
primeira parte:
assim e no UseMyThreads podemos usar um JOIN
Thread t1 = new MyThread(new X()).start();
t1.join;

segunda parte da resposta é meter o método 1 como synhcronized
na classe MyThread
public synhcronized metodo1(){ … }
eu posso fazer synhcronized ao nivel do método no run nao posso só internamente

==teórica) #exame 19-20 especial
1.
considere uma api web (web service) que incluir entre outras s seguintes URI:
1) /users?address=”coimbra”
2) /users/delete?address=”coimbra”
3) /users/coimbra
4) /users/coimbra10
extras
5) /users/10/update?address=”coimbra”
6) /users/insert?id=10&name=”ana”&address=”coimbra”

a) indique para cada uma um possivel significado
r:
1) lista de utilizadores com morada em coimbra
2) manda apagar da lista de utilizadores com a morada em coimbra
3) lista de utilizadores que vivem em coimbra
4) identifica o utilizador com o codigo 10, dos utilizadores que vivem em coimbra OU a 10ª página de utilizadores de coimbra OU o registo 10 em coimbra
extras
5) um pedido de update da morada do utilizador com o codigo 10
6) inserir nos utilizadores com os dados…

b) identifique, justificando a URI que não serve os principios REST e apresente, igualmente uma alternativa que esteja correcta
olhar para as primeiras 4
2) tem um verbo, a URI só deve identificar o recurso a URI correta seria
as URI identificam o recurso, as acções é através de um verbo, que vai na mensagem http

==teórica) #exame 19-20 especial
2)
explique o conceito de callback/notificação assincrona em sistemas distribuidos e de que forma pode conseguir-se esta funcionalidade em aplicações baseadas no paradigma de objecto remoto (e.g JavaRmi). não recorra a código na resposta
explique o conceito de callback/notificação assincrona em sistemas distribuidos e de que forma pode conseguir-se esta funcionalidade em aplicações baseadas em sockets TCP (e.g., instâncias da classe java.net.Socket na linguagem java). não recorra a código na resposta
explique o conceito de callback/notificação assincrona em sistemas distribuidos e de que forma pode conseguir-se esta funcionalidade em aplicações baseadas em sockets UDP (e.g. instâncias da classe java.net.DatagramSocket na lingiagem java). não recorra código na resposta)

==teórica) #exame 19-20 especial
3.
consider a seguinte instrução:
java.rmi.Naming.unbind(“rmi://reg.isec.pt/5001/time”);
java.rmi.Naming.bind(“rmi://reg.isec.pt/5001/time”, timeService);
java.rmi.Remote r = java.rmi.Naming.lookup(“rmi://reg.isec.pt:5001/time”);

a) explique o que identificam os elementos “reg.isec.pt”, “5001”, e “time”
b) deduza a sequência de acções/passos principais desencadedos quando esta insgtrução é invocada (ligações estabelecidas, mensagens trocadas, etc.) a resposta não deve incluir código

==teórica) #exame 19-20 especial
4. para uma aplicação desenvolvida em Java aceda a um determinado sistema de gestão de base de dados (SGBD), pode recorrer-se à API JBDC. para o efeito é necessário usar um driver adequado ao tipo de SGBD acedido (por exemplo, mysql-connector-java-5.1.45-bin.jar para MySQL e obdc8.jar para oracle)
explique:
a) o que é comum a todos os drivers JDBC, independentemente do SGBD alvo;
r:
todos oferecem a API jbdc, é o api do jbdc
b) o que difere entre drivers JDBC destinados a SGBD distintos
r:
são implementados de forma diferente
o protocolo de comunicação é diferente do procotolo de comunicação MySQL

==prática)
1. (pergunta de api rest) considere a seguinte mensagem HTTP destinada a pedir, a uma determinada API/serviço web, a lista de undiades curriculares concluidas por um determinado aluno, identificado através do seu número de estudante num determinado ano lectivo e assmindo um esquema de autenticação baseado em tokes:

POST /alunos/list/ucs/concluidas HTTP/1.1
Host: api.pd.com
User-Agent: curl/7.55.1
Student-number: 201012345
Year: 202-21
Accept: */*

{“Authorization”:”TK asdasdasdsadsadsad”}

Este pedido apresenta várias incorreções relativamente à aplicação dos principios REST e à estruturação habitual de pedidos HTTP (i.e, colocação da informação no formato adequado e na parte certa da mensagem).
a) complete o pedido HTTP seguinte de modo a que este seja uma reformulação correcta da mensagem anterior
R:
as boas práticas dizem que:
na URI deveia ser um GET
GET /alunos/list/ucs/concluidas HTTP/1.1
o token deve estar no cabeçalho e num campo chamado Authorization
e o numero do aluno devia estar no corpo do pedido ou colocar mesmo na URI, mas neste caso até podiamos fazer uso do token
e também existe um erro em /alunos/list/ucs/concluidas pois o list devia surgir no final. partir de uma coisa mais genérica e vamos afunilando

ou resposta possivel (com parametros):
GET /alunos/22232323/ucs/concluidas?year=2020-21 HTTP/1.1
Host: api.pd.com
User-Agent: curl/7.55.1
Student-number: 201012345
Accept: */*
Authorization:TK asdasdasdsadsadsad

ou
GET /alunos/22232323/ucs/concluidas?year=2020-21&nota-minima=15 HTTP/1.1

b) complete a mensaem HTTP seguinte, sendo este um exemplo de resposta ao pedido anterior e considerando que é devolvida uma lista com duas unidades curriculares, sendo cada uma caracterizada por apenas dois atributos: cod_uc e nota. Pode atribuir qualquer valor aos atributos desde que façam algum sentido no contexto da pergunta
HTTP/1.1 ??????
Content-type: application/json
Date: Tue, 2 Fev 2021 10:13:05 GMT
?????

r:
HTTP/1.1 200 OK
Content-type: application/json
Date: Tue, 2 Fev 2021 10:13:05 GMT
[{“cod_uc”:”1111″,”nota”:”11″},{“cod_uc”:”2222″,”nota”:”12″}]

cuidados:
ao invés de: Content-type: application/json
pode ser application/txt
ou pode ser application/html

==prática)
2. explique, sem recorrer a código, quais são as ações principais que o método stop realiza ao ser invocado no pedaço de código abaixo (nota: não é o objectivo do méotod, ou seja, parar um senor remoto com código igual a 2, que deve explicar)
import Java.rmi.*
Remote ref = Naming.Lookup(“rmi://193.138.11.34/sensors_controller”);
ControllerInterface remoteSenosrs = (ControllerInterface) ref;
remoteSenosrs.stop(2);

a resposta deve obrigatoriamente mencionar os termos “serviço RMI”, “TCP”, “porto de escuta automático”, “endereço de IP”, “serialização binária” ou algo relacionado, “pedido” e “resposta”, entre outros possiveis. Quando referir os termos “porto de escuta automático” e “endereço IP” e “endereço IP” deve igualmente indicar onde os respetivos valores estão guardados. seja analitico e apresente a resposta soba forma de uma sequência ordenada de acções/passos (10 no máximo)

r:

==prática)
1. Pretende-se que desenvolva, em linguagem Java, um método atendendo aos seguintes requisitos:
Protótipo do método pretendido:
void processRequest(Socket s) throws Exception;

O socket TCP s já se encontra criado e conectado a um par remoto, estando pronto para o envio e recepção de dados;
O médoto processRequest vai recebendo objectos serializados do tipo Request através do socket s até que ocorra uma excepção qualquer;
A classe Request possui, entre outros, os métodos int getUdpPort(), String getIpAddress() e String getMsg();
Para cada objecto Request recebido, a string devolvida pelo método getMsg() é enviada, através do protocolo UDP (DatagramSocket) e em formato texto (i.e., sequência de caracteres) para o destino com o endereço IP e o porto estipulados;

Quando ocorre uma excepção de qualquer tipo, o método processRequest:
Encerra o socket s;
Apresenta a mensagem associada à excepção;
Volta a lançar a excepção, o que faz com que termine.

import java.net.*;
void processRequest(Socket s) throws Exception

{
. . .
while(true)
{
/* Receive a serialized Request object */
. . .
/* Transmit the specified message to the specified IP
address and UDP port.
The message is transmitted as a sequence of characters (i.e., it is not transmitted as a serialized String object).

*/
. . .
}
}

r1:
para:
O médoto processRequest vai recebendo objectos serializados do tipo Request através do socket s até que ocorra uma excepção qualquer;
temos:
criar um objecto inpuToStream
e vamos fazendo read object com cast para Request

para:
Para cada objecto Request recebido, a string devolvida pelo método getMsg() é enviada, através do protocolo UDP (DatagramSocket) e em formato texto (i.e., sequência de caracteres) para o destino com o endereço IP e o porto estipulados;
temos:
pega no Request e no getMsg() e getBytes()
e de seguida construir um dataGramPacket com o inetadress passado o byname o getIpAddress() e getUdpPort() criar o DatagramSocket e enviar
e apanhar as excepções

r2 final:
import java.net.*;
class Exame{
void processRequest(Socket s) throws Exception
{

if(s==null){
//return;
throw new NullPointerException(“socket s passado como null”);
}

DatagramSocket ds =null;//crio e vi sempre usado o mesmo socket
//e foi passado para fora do try para poder criar a excepção
try{
ObjectInputStream oin = new ObjectInputStream(s.getInutStream()); //aqui porque só se abre um ficheiro uma vez e já ta
ds = new DatagramSocket();

//para usar o DatagramPacket
while(true)
{
/* Receive a serialized Request object */
//
Request req = (Request)oin.readObject();

. . .
/* Transmit the specified message to the specified IP
address and UDP port.
The message is transmitted as a sequence of characters (i.e., it is not transmitted as a serialized String object).

*/
//se fosse necessário sair do ciclo
if(req.getMsg().equals(“EXIT”){
return;
}

DatagramPacket pkt = new DatagramPacket(req.getMsg().getBytes(), req.getMsg().getBytes().lenght, InetAddress.getByName(req.getIpAddress()), req.GetUdpPort() );
//ObjectInputStream oin = new ObjectInputStream(s.getInutStream());//sai daqui

//agora o datagramSocket para enviar a mensagem
//DatagramSocket ds = new DatagramSocket(); //sai daqui
//enviar a mensagem
ds.send(pkt);

}
} catch(Exception e){
System.out.println(“Excepcao :”+ e );
//e para lançar a excepção é preciso ainda fazer:
throw e;
}
finally{
try{
s.close(); //este try abafa a IOException que for gerada, apenas aqui
}catch(IOException e){}
if(ds!=null){ds.close();}
}
}
}

//tudo que é feito no finally é feito ao inves de usar
catch(Exception e){
s.close();

}

r3:
e se no socket podermos receber objectos do tipo Request ou do tipo XPTO
import java.net.*;
class Exame{
void processRequest(Socket s) throws Exception
{
. . .
while(true)
{
/* Receive a serialized Request object */
ObjectInputStream oin = new ObjectInputStream(s.getInutStream());
Object obj = oin.readObject();

if(obj instanceof Request){
((Request).oin).getUdpPort();
}else if(obj instanceof XPTO){
((XPTO).oin).getUdpPort();
}

. . .
/* Transmit the specified message to the specified IP
address and UDP port.
The message is transmitted as a sequence of characters (i.e., it is not transmitted as a serialized String object).

*/
. . .
}
}
}

==prática)
3. (RMi) Pretende-se que desenvolva um serviço remoto Java RMI, com um mecanismo de callback, atendendo aos seguintes requisitos:
Nome da classe que representa o serviço: MessageReflector;
Interface remota implementada pelo serviço MessageReflector:
Nome: MRInterface;
Métodos:
boolean registerClient (MRClientInterface cliRef);

Se ainda não existir, acrescenta a referência RMI passada como argumento a uma lista interna e devolve true. Se já existir, ignora o pedido e devolve false.
Notas:
1. Em vez de uma lista, também pode recorrer a um conjunto;
2. Cada cliente implementa um serviço RMI baseado na interface remota MRClientInterface.

boolean unregisterClient (MRClientInterface cliRef);
Se existir, remove a referência RMI passada como argumento da lista interna e devolve true. Caso contrário, devolve false.

void broadcastMessage(String msg);
Comunica a string passada como argumento a todos os clientes registados. Para o efeito, invoca o método void postMessage(String msg) pertencente à interface remota MRClientInterface. Qualquer problema que surja na invocação do método postMessage leva à eliminação da respectiva referência remota (i.e., do cliente) da lista interna.

int getNumRegisteredClients();
Devolve o número de clientes registados (i.e., o número de referências remotas existentes na lista interna).

r:
Class MessageReflector extends unitCastRemoteObject implments MRInterface {
//fazer o construtor vazio
MessageReflector{}
//e os métodos
boolean registerClient(){}

//enivar a todos
com broadcastMessage e ir ao arrayList e chamar

}

r2 final:
notas:
os clientes devem registar.se, isto é , invocar um método do serviço
não é preciso o main do servidor

//a base sem RMi
interface MRClientInterface extends Remote{
void postMessage(String msg) throws RemoteException;
}

public interface MTinterface{

//métodos
boolean registerClient (MRClientInterface cliRef);
boolean unregisterClient (MRClientInterface cliRef);
void broadcastMessage(String msg);
int getNumRegisteredClients();

}

//classe que implementa a interface
class MessageReflector implements MRInterface
{
//lista de referencias remotas para os clientes
List clientList = new ArrayList<>();

@Override
public boolean registerClient (MRClientInterface cliRef){
return false;
}

@Override
boolean unregisterClient (MRClientInterface cliRef){
return false;
}

@Override
void broadcastMessage(String msg){
}

@Override
int getNumRegisteredClients(){
return -1;
}

}

//agora aplicar o RMi
interface MRClientInterface extends Remote{
void postMessage(String msg) throws RemoteException;
}

public interface MTinterface extends Remote{
//métodos
boolean registerClient (MRClientInterface cliRef) throws java.rmi.RemoteException;
boolean unregisterClient (MRClientInterface cliRef)throws RemoteException;
void broadcastMessage(String msg) throws RemoteException;;
int getNumRegisteredClients() throws RemoteException;;
}

//classe que implementa a interface, e agora já é um serviço e surge extends UnicastRemoteObject
//servidor concorrente UnicastRemoteObject
//e cada cliente que se ligue vai ser criada uma thread
class MessageReflector extends UnicastRemoteObject implements MRInterface
{
//lista de referencias remotas para os clientes
List clientList = new ArrayList<>(); //este atributo é mexido por várias threads, vou então serializar

//e falta o construtor
public MessageReflector () throws RemoteException{}
//ou public MessageReflector (Listl) throws RemoteException{}

//e em todos os métodos da interface remota surge throws RemoteException
@Override
public synhcronized boolean registerClient (MRClientInterface cliRef) throws RemoteException{
//se já existe, do tipo equals
if(clientList.contains(cliRef)){
return false;
}
return clientList.add(cliRef);
}

@Override
boolean synhcronized unregisterClient (MRClientInterface cliRef) throws RemoteException{
return clientList.remove(cliRef);
}

@Override
void synhcronized broadcastMessage(String msg) throws RemoteException{
//versão1
for(MRClientInterface cli: clientList){
try{
cli.postMessage(msg);
}catch(RemoteException e){
clientList.remove(cli);
}
}
//versão2 com indices
for(int i = 0 ; i<clientList.size();i++){
try{
clientList.get(i).postMessage(msg);
}catch(RemoteException e){
clientList.remove(i–);
//i–;
}
}
}

@Override
int synhcronized getNumRegisteredClients()throws RemoteException{
return clientList.size();
}

}

//ou synhcronized por bloco
@Override
public boolean registerClient (MRClientInterface cliRef) throws RemoteException{
synhcronized{

}
return false;
}

Tags : , ,

Proposta de trabalho (em Lisboa)

“A Marmalade Game Studio PT tem neste momento 4 vagas abertas:
– Game Producer – LINK
– UX/UI Artist – LINK
– Game Designer – LINK
– QA Game Tester – LINK
Deixo as especificações de cada vaga nos comentários, e se sentirem que são um bom fit, enviem a vossa candidatura diretamente pelo site ou para o email cristiana.serra@marmalademail.com”

Game Producer, The role:
Work closely with project leads to guide projects by overseeing internal resources, observing deadlines, and escalating and resolving issues that might compromise the quality of delivery
Manage releases and submissions
Partner with multi-discipline teams such as design, art, programming, and QA on multiple projects at different stages of development
Create and update schedules and tasks
Keep issue tracking lists up to date
Reviewing bugs for clarity and provide status reports on the state of the bug database
Product testing to monitor progress and state of the project
The Ideal Candidate:
Experience in video game production or in another project management role
Excellent time management skills and ability to multitask and prioritize work
Strong organizational and planning skills
Strives for high quality and pays attention to detail
Excellent written and verbal communication skills
Ability to give and take constructive feedback
Comfortable in a fast-paced environment and can work to deadlines

UX/UI Artist, Responsibilities:
Work in a team to define the look and feel of our user interface
Be responsible for the UI of the game, producing style guides, rule sets, and templates
Create, implement and iterate on UI assets and animations
Provide concept sketching, wire-framing, and high-fidelity UX mockups/prototypes.
Work closely with art, design, production, and developers to iterate on the best solutions to UX and UI challenges
Requirements
Experience as a UX/UI Artist in the games industry or another relevant industry
Strong graphic design skills showcased by a portfolio that meets the quality of Marmalade Games
Ability to explore and create different styles
Experience creating UX prototypes and wireframes
Excellent understanding of typography, composition, color theory, visual design, and interaction design
Basic knowledge of animating assets for conceptual purposes
Ability to respond efficiently to problems and conflicts that may influence game development
Great communication skills
Knowledge of Photoshop, Illustrator, and Unity

Game Designer, The role:
Contribute with ideas for new game concepts, design features, mechanics, and new solutions for existing games
Create game design documentation, game flows, mock-ups, and paper prototypes
Work closely with the Lead Game Designer and fellow designers to iterate and improve your designs
Work closely with the producer to understand the briefs and requirements for the design function within the project
Communicate your designs to a team of artists, designers, and programmers
Analyze and test games from a user-experience point of view, proposing iterations
Basic statistic knowledge to be able to balance ingame values
The Ideal Candidate:
Previous experience as Game Designer working on professional or personal projects
Strong motivation to create games and to develop your Game Designer career
Highly creative, you are able to come up with game concepts, new features, and brilliant solutions for different projects
Good understanding of UX – you have a user-centric approach, always aiming to create the best experiences for the players
Excellent verbal, written, and visual communication skills
You understand and love an entrepreneurial environment – you won’t be a cog in a machine, you will wear many hats and have a clear impact on the products
A passion for board games is a plus
Driven-minded, proactive, able to adapt quickly, and responsible for your own work, owning multiple steps of the process
Experience with Unity is desirable but not mandatory

QA Game Tester, Responsibilities
Work in a team to define the look and feel of our user interface
Be responsible for the UI of the game, producing style guides, rule sets, and templates
Create, implement and iterate on UI assets and animations
Provide concept sketching, wire-framing, and high-fidelity UX mockups/prototypes.
Work closely with art, design, production, and developers to iterate on the best solutions to UX and UI challenges
Requirements
Experience as a UX/UI Artist in the games industry or another relevant industry
Strong graphic design skills showcased by a portfolio that meets the quality of Marmalade Games
Ability to explore and create different styles
Experience creating UX prototypes and wireframes
Excellent understanding of typography, composition, color theory, visual design, and interaction design
Basic knowledge of animating assets for conceptual purposes
Ability to respond efficiently to problems and conflicts that may influence game development
Great communication skills
Knowledge of Photoshop, Illustrator, and Unity

+infos(oficial): https://www.marmaladegamestudio.com/

Tags : ,

Parte 1 de 37, apontamentos

#sockets Java
na comunicação na internet entre aplicações existem dois protocolos: o UDP e o TCP
o ip identifica a máquina, e o porto ajuda a app a saber que a comunicação é para essa app

UDP – enviamos mensagens (datagramas) e que inclui:
dados da mensagem (conteúdo) e um envelope com ip, porto de destino e IP porto de origem
UDP não faz verificação, são enviadas cartas (como se fosse um envelope)

TCP – temos um fluxo de BYTES, diferente de UDP

existem classes em java importantes para proceder à comunicação:
inetadress, manipula relações com endereços e resolução de nomes
datagram packt, tem atributos e métodos e que vai ser encapsulada num datagramPackt
datagram socket, só o UDP tem isto porque se trabalha com datagrams

o Inetadress:
encapsula endereços IP
não tem construtor
tem métodos estáticos

getByName(IP ou nome)
métodos a aplicar depois:
getHostAddress
getHostName
getAllByName(array)

para saber qual o meu ip:
inetAdress localAdress = InetAddress.getLocalHost();
e uma exceção:
catch(UnknowHostException e){

}

DataGramPacket
encapsula as mensagens individuais
construção de um datagram UDP para envio

Uma mensagem tem um endereço ip, um porto e uma mensagem (conteúdo)

DataGRamPAcket packet = new DataGramPAcket(data, data.length, addr, 2000);
data vem byte [] data = new byte[128]
data.length vem 128
addr vem InetAdress addr = InetAdress.getByName(“192.168.0.1”);
2000 vem o porto

Operação de receção de um DATGRAM PACKET

assim no recetor uso outro construtor

try{
DATAGRAMPACKET packet = new DTAGRAMPACKETS (new byte[256], 206);
DATAGRAMSOKCET socekt = new DATAGRAMSOCKET(2000);
boolean finished = false;
while(!finished){
socket.receive(packet);

}
socket.close();
}catch

#protocolo UDP
a class DATAGRAMPACKET tem vários métodos:
send
receive (bloqueante)
close
setTimeout(0), desbloqueio o TIMEOUT é um no TIMEOUT

o lenght, consoante o contexto de utilização um determinado packet pode significar:
quantidade para enviar
quantidade para receber/aceitação
quantidade que foi recebida

#exemplo como enviar uma mensagem:
DATAGRAmSOCKET socket = new DATAGRAMSOCKET();
DATAGRAMPACKET packet = new DATAGRAMPACKET( new byte[256], 256);
packet.setAddress(INETADDRESS,getByName(someHost));
packet.setPort(2000);
boolean finished = false;
while(!finished){
//-> escrever no buffer do packet
seocket.send(packet);
//-> verificar se existe mais coisas para enviar
}
socket.close();

#protocolo TCP
relembrar que no UDP:
DATGRAM PACKT, que encapsula uma mensagem com endereços (endereço, porto, dados recebidos)
DATAGRAM SOCKET, end point de uma comunicação, onde enviamos e recebemos bytes
ÎNETADRESS, serve para encapsular o endereço ip e os nomes do dns

Protocolo TCP:
não é orientado a mensagens;
serve para comunicação ponto a ponto (entre dois extremos)
abstração do socket (ligação virtual)
o socket está ligado a um endereço remoto (end point), surge o conceito de fluxo de dados
o que vai ser colocado no buffer são bytes e não mensagens (é o mesmo que escrever num ficheiro)
enviar bytes para uma aplicação remote, como se estivesse a escrever num ficheiro

UDP não faz controlo de fluxo, não verifica o numero de sequência, não deteta se existem mensagens perdidas, não pede retransmissão (envio uma carta e esqueço a carta)

TCP, as instâncias de TCP, trocam informações, mensagens de controlo, confirmações, timeouts, para garantir que os bytes são colocados no socket de destino pela mesma ordem e sem haver perda de bytes no meio

#entrada/saída
input stream e output stream, são classes abstratas cujos métodos não estão implementados

vão-se é obter subclasses que vão implementar métodos.

INPUTSTREAM (vou ter um read) e OUTPUTSTREAM (vou ter um write) geram exceções IOException

usar SCOKET ou ArrayBytes ou Ficheiro, vai ser indiferente

pseudocódigo:
a conexão (servidor, recebe a ligação)
xxServerSocket // Socket socket = new Scoket (“www…”, 80);
a transferência
xx Socket

outros exemplos:
socket (host, port );
socket (host, port, bindAddress, localhost)

onde bindAddress, especifica-se a placa (por exemplo um das duas placas do portátil, rede sem fios)

onde localhost, porto do cliente

por exemplo: socket(…, …, InetAddress.getByNumber(“10.10.10.10”), 5001);
a entrada e saída de dados tem que ser feita através desta placa de rede, mas pode acontecer que não queremos restringir placas mas fixar porta 5001, então surge
socket(…, …, InetAddress.getByNumber(“0.0.0.0”), 5001);

exemplo no cliente:
try{
Socket mySocket= new Socket(“www.sol.pt”, 80);
….
}catch(Exception e){
System.err.println(“Err – ” + e);
}

O socket TCP, tem métodos:
getOutPutStream()
getInputStream()
getLocalPort
getPort, acesso ao porto remoto
GetTimeout()

por exemplo no cliente:
try{
Socket socket = new Socket(someHost, somePort);
BufferReader reader = new BufferReader(new InputStreamReader(socket.getInputStream()));
PrintStream pstream = new PrintStream(socket,getOutPutStream());
}catch(IOException e){
System.err.println(“erro – ” + e);
}

em que: socket.getInputStream(), faço o read
em que: socket,getOutPutStream(), faço write bytes

por exemplo, operação de leitura e que não fique bloqueado para sempre:
try{
Socket socket = new Socket(someHost, somePort);
socket.setTIMEOUT(2000); // onde setTIMEOUT(0);//desliga-se o TIMEOUT
BufferReader reader = new BufferReader(new InputStreamReader(socket.getInputStream()));
PrintStream pstream = new PrintStream(socket,getOutPutStream());
}catch(Interrupt IOException e){
timeoutflag = true;
}catch(IOException e){
System.err.println(“erro – ” + e);
System.exit(0);
}

#protocolo TCP
serverSocket(porta) e tem alguns métodos como é o caso do close()

o serverSocket não serve para enviar dados e receber, este só serve para aceitar ligações

#aplicações multicast
endereços de classe D (11110)
representam grupos (ou endereços)
como enviar para um grupo e como receber?
escrever via broadcast (255.255.255.255 6001)
assim todas as aplicações que estão a correr na mesma máquina no domínio de difusão e que tenham um socket associado ao porto 6001 vão receber a mensagem

exemplo:
InetAddress group = InetAddress getByName(“224.1.2.3”);
MulticastSocket socket = new MulticastSocket(port); //port é o porto de escuta
socket.joinGroup(group); //joinGroup(group) para apanhar o que aparece na rede destinada ao 22.4.1.2.3 port
socket.setTimeToLeave(1); // setTimeToLeave, tempo de vida da mensagem, neste caso (1) elimina, e fica a zero e não reencaminha

e para enviar e receber:
DATAGRAM packet = new DATAGRAM (buffer, buffer.lenght, group, port);
socket.send(packect);
//como pertenço ao mesmo grupo, também recebo
byte[] response = new byte[1024];
DATAGRAM packet = new DATAGRAMPACKET(response, response.length);
socket.receive(packet);

Exemplo:
String NICID = “127.0.0.1”,”en0″,…
NETWORKINTERFACE nif;
try{
nif = NETWORKInterface.getByInetAddress.getByName(NICID));
}catch(Exception ex){
nif = NETWORKInterface.getByName(NICID);
}
socket = new MultiCast(port);
socket.joingroup(new InetSocketAddress(group, port), nif);

em que:
joingroup, associo a um grupo
InetSocketAddress, completo IP+porto
nif, qual a interface de rede a associar ao grupo

#serialização de objectos
Esta é a forma mais simples de trocar informação
A informação está encapsulada em objectos
Serialização vs DesSerialização

a Serialização é binária, mas exibe em formato de texto como o JSON

#serialização de objectos, ligações TCP
exemplo:
s = new Socket(serverAddress, serverPort); // estabelecer a ligação
in = new ObjectInputStream(s.getInputStream());
out = new ObjectOutPutStream(s.getOutPutStream()); //enviar
out.writeObject(object to transmit); //escrever no object
//ou out.writeUnShared(object to transmit); //deve ser usado, por exemplo para enviar um arraylist então o usado é o unshared para evitar caching
out.flush();

ou usar writeobject mas fazer antes o out.reset() e ficaria:
out.reset();
out.writeObject(object to trnsmit);

//e do outro lado faz-se a leitura
returnObject = (MyClass)in.readObject();

#serialização de objectos ligações UDP

o UDP não tem fluxo de bytes, datagrams)

exemplo para o envio:
s = new DatagramSocket();
bout = new ByteArrayOutputStream();
out = new ObjectOutputStream(bout);
out.writeObject(Object to transmite);
//ou
out.writeUnshared(object to transmite);
out.flush();
packet = new DatagramPacket(bout.toBytetoarray(), bout.size(), serverAdress, serverPort);
s.send(packet);

exemplo para receber:
packet = new DATAGRAM(new Byte[MAX_SIZE], MAX:SIZE);
s.receive(packet);
n = new ObjectInputStream(new ByteArrayInutStream, packet.getData), 0, packet.getLenght());
returnObject = (MyCalss) in.readObject();

#threads
processo é diferente de thread
todas as threads pertencem ao mesmo processo, as threads são linhas de execução

as threads podem ser iniciadas em dois modos distintos:
modo por omissão, modo normal (modo utilizador) // bloqueante
modo através do daemon(serviço para correr em background) // não bloqueante

Uma aplicação em java termina quando já não existe qualquer, em que já não existem threads em modo utilizador activas.
As thraeds activas em modo de utilizador, mesmo chegando ao fim do main elas continuam activas, se forem as threads em modo daemon, chegada ao fim do main elas terminam

public class RunnableThreadDemo implements java.long.Runnable
{
public void run(){
SystemOut.println(“….”);
}
public static void main (String args[]){
System.Out.println(“…”);
Runnable run = new RunnableThreadDemo();
System.Out.println(“…”);
thread t1 = new Thread(run, “thread 1”); //run, é o nome da thread
System.Out.println(“…”);
thread t2 = new Thread (run, “trhead 2”); //run é o nome da thread
System.Out.println(“…”);
t1.start();
t2.start();
}
}

a diferença entre os dois modo de criar threads pode ser importante
assim o método II é melhor que o método I, já que posso criar várias threads baseadas no mesmo objecto runabble e elas vão partilhar os mesmos membros. posso assim ter várias threads concorrentes mas a trabalhar sobre os mesmos dados.
E outra vantagem é contornar uma das limitações do já de não haver herança múltipla

class ExtendThreadDemo extends java.long.thread // esta classe não pode estender outro tipo de objecto

assim consigo dar a volta a isso fazendo/usando:
class ExtendThreadDemo implements java.long.thread

eu posso implementar vários tipos de classes mas só posso derivar de uma classe

threads, faz-se o new thread mas depois tem que se fazer o start, e  só depois do start o new cria um objecto que representa uma thread, mas o start lança de forma efectiva

#interromper threads

é desaconselhável

thread sleep- > interreupt -> resume
alternativa é a thread que a lançar, fechar a socket, ao fechar é gerada uma exceção na thread e antes de fechar o socket eu coloco um atributo na thread para ela saber que é para terminar

#parar threads usar o stop

fazer uso de uma boolean e “avisar” que vai ter que encerrar

#operações sobre threads

verificar se ainda está viva:
if(t1.isAlive(){ //booleand

}

e nunca usar um while..

#método join

bloqueia, e só regressa depois da thread estar inactiva
t1.join(1000,10000);
em que 1000, é o numero máximo de segundos milésimo de segundos
100000, são nanosegundos

exemplo:
thread die = new WaitForDeath(); //a thread
die.start(); //inica a thread
die.join(); // bloqueia ate a thread terminar

#sincronização de threads

concorrência no acesso a recursos partilhados
solução: serializar o acesso ao recurso partilhado, isto é, enquanto uma thread está a mexer nos recursos, as outras threads que pretendam aceder aos recursos ficam bloqueadas, ou seja, surge então o objecto sincronização

acesso mutuamente exclusivo
assim se surgir outra thread que quer aceder a métodos não podem executar esse ou outro métodos do objecto

a sincronização pode se feita:
método // bloqueia apenas alguns dos métodos
bloco de código

#sincronização ao nível do método// thread safe

public synchronized void mudaData() {…}

public synchronized void changeData() {…}

exemplo:
public class someClass{
public synchonized void ChangeData(){…}
}

O = new someClass();
t1 e t2 têm a referêcnia para O
t1 chama o método changeData
e se t1 chamar o méotodo changeData, fica bloqueada

#sincronização ao nivel do bloco de código

sincronização referente a um bloco
não é necessário os métodos serem synchronized
existe o thread-safe (serializado) sem necessidade de ter acesso ou alterar o código fonte
synchronized (Object O){

}

esta forma dá mais flexibilidade

se for só um classe minha será mais fácil colocar o método sincronized mas se for uma que já existe será o modo bloco

#grupos de threads
é limitado, um conjunto de operações limitado

#comunicação entre threads
no mesmo processo, no mesmo espaço de endereçamento é feito através de pipes de comunicação:
_troca directa de dados entre threads
_comunicação bidirecional
(temos usado um BufferedReader bin = …

#notificação entre threads
surgem os métodos:
Object.wait();
Object.notify();
Object.notifyAll();

#prioridades das threads
abordagem round-robin
prioridades variam entre:
1 mais baixa
10 mais alta

com uso de:
MAX_PRIORITY
NORM_PRIORITY
MIN_PRIORITY

métodos:
t.setPriority(thread.MIN_…)

#servidores TCP concorrentes

while(true){
cliente = socket.accepts();
t = new thread();
t.start();

}

#computação paralela baseada em múltiplas threads
processamento real

#exercicio
resolver um proxy: é uma aplicação que serve de intermediário entre duas aplicações em rede
usando TCP: (guarda log dos acessos)

o proxy para fazer logs do que é trocado

um proxy para servidor é uma ponte. o servidor do mail do isec pop-isec.pt:110

um server socket no porto 8080, e crio uma thread que vai tratar o que se pasa no socket, mas essa thread tem outra socket para comunicar com o servidor de mail do isec (cliente-servidor)
para cada cliente exist uma thread cirada
essa thread tem um socket para comunicar com o cliente
essa thread tem um socket para comunicar com o pop.isec (servidor)

mais ainda não se consegue receber um char e reencaminhar porque existe um sistema de bloqueio de espera de mensagem no socket
usar um timeout não se pode fazer porque é espera activa, assim para cada cliente vai ser necessário duas threads, e as duas threads têm acesso aos mesmos sockects
uma thread tem acesso a ler bloqueada num socket e aquela que recebe envia para outro socket e outra faz o inverso

#arquitectura n-tier
separação lógica e física
a arquitetura 3-tier é mais habitual:
apresentação
lógica (do negócio)
dados (MySQL)

o 3-tier, é parecido com o MVC:
camada de apresentação -> cliente
camada lógica -> SGRDS e servidores
camada de dados -> usar o MySQL

#JDBC
java database connectivity

Connection con = DriverManager.getConnection(BD, username, password);
statment stmt = con.createStatment();
resultset rs = stmt.executeQuery(“select * from table;”);
while(rs.next){
int x = rs.getInt(“a”);
String s = rs.getString(“b”);
float x = rs.getFloat(“c”);
}

porque é que temos que usar drivers diferentes para bases de dados diferentes? se tiver que usar SQL, porque é que tenho que usar um driver diferente se tiver que usar ORACLE?
porque o protocolo de comunicação é diferente

#inovação remota de métodos
o middleware, sistema que vai abstrair o programador dos aspectos de baixo nivel, nomeadamente de:
troca de mensagens/comunicação
protocolo de comunicação
sistemas operativos
hardware

exemplos de middleware:
RMi
RPC
CORBA
NetRemoting

um proxy que tem os métodos, e eu localmente tenho um objecto que tem os mesmos métodos
RPC é o inicio da história para o paradigma dos sistemas distribuídos (miiddleware)

os passo do RPC
passo1: o servidor fica a correr e vai-se registar na porta 111
passo2: o cliente solicita o porto do servidor
passo3: recebe a porta
passo4: faz o pedido
passo5: recebe a resposta

#introdução ao java RMi
agora ao invés de se chamar funções, vou chamar métodos usando objetos remotos

o input ao sistema é uma interface (conjunto de protótipos de métodos)

#arquitectura java RMi
existem servidores, clientes, RMI registry

os passos do RMi:
1_ o servidor regista no Rmi registry
2_ o RMiregistry providencia referências ao cliente

o que é que um serviço e um proxy têm em comum?
a interface, os métodos que implementam

o Sturb (ou proxy) é do lado do cliente e actua como um proxy. Implementa neste a interface remota, é invocado pelo cliente, envia mensagem ao serviço.
o Skeleton é do lado do servdor, aguarda pedidos na aplicação servidora, invoca o método pretendido, devolve o resultado ao Sturb.

A comunicação é feita via serialização e por isso todos os argumentos que se passam em funções e resultados têm que ser serializados

porque razão é que o java RMi nas interfaces remotas tem que ter os argumentos e os resultados serializados?
porque o sistema, invocamos o método remoto e o que acontece é que é enviado um objecto que representa um pedido para o servidor, e o RMi faz a serialização dos objetos logo o pedido vai ter a identificação do método, etc, e assim tem que ser tudo serializado

#Arquitectura RMi
permite chamar os métodos de um serviço que não está na minha máquina, sendo que existem três componentes principais e que são: servidor RMi, cliente RMi, RMi registry

o servidor RMi: usa TCP, com um server socket à escuta num porto, é concorrente (sempre que existe um pedido de ligação cria uma thread, essa thread recebe pedidos, vê qual o objecto e qual o método para executar, e executa e devolve o resultado na origem.) No servidor só temos que especificar o que o método faz

o cliente RMi: aplicação que tem referências para objectos remotos. O cliente quando contacta o RMi registry recebe o Sturb. E no Sturb tem dois membros obrigatórios: o ip da maquina e o porto de escuta

o RMi registry: é o serviço que está à escuta num porto automático TCP, sendo que os clientes contactam o RMi Registry TCP

#Passos principais
1) definir a interface remota: métodos, com argumentos e valor de retorno (Sendo que tudo o que é valor de retorno tem que ser serializavel)
2) implementar o serviço: ter classes que implementam a interface
3) é preciso um servidor (uma aplicação que cria objecto, vai registar no RMi registry)
4) os clientes (é uma aplicação que tem que invocar o método no serviço XPTO, assim em vez desta aplicação fazer um NEW, vai obter uma referência remota, contact o servidor, e se o serviço existir eu obtenho o sturb/proxy (referencia remota))
5) lançar o RMi registry (1099, TCP)
6) lançar o servidor
7) correr os clientes

#interfaces remotas
por exemplo controlar uma lâmpada remotamente

surge então uma aplicação em java, em que no main faz-se um NEW controlador (que poderia ter alguns parametros) e nesta app apenas surge a opção do menu de ligar e desligar.
ainda no main do servidor, teria que criar um server socket que vai fazer accepts, se quiser qe seja concorrente lanço threads
então e na comunicação posso usar mensagens curtas, booleans, ou objectos serializados com mais campos

do lado do cliente existe um socket que constroi os pedidos
usando o RMi vamos abstrairnos desta situação, com o RMi vai ser mais simples pois não se pensa em mensagens, mas sim nos servidores, e quais os métodos que temos nos servidores e as apps clientes vão invocar métodos do utilizador (gets, sets, ..) (por baixo existe o TCP, serialização, mas não somos nós a tratar disso)

No RMi temos que obrigatóriamente usar em todos os métodos o throws java.rmi.remoteException
public void on() throws java.rmi.remote.exception

e as interfaces remotas têm que ser:
public interface Classe extends java.rmi.remote {
public void ont() throws java.rmi.remote.exception

muito importante:
throws java.rmi.remote.exception
e
public interface Classe extends java.rmi.remote

assim:
1) no servidor existem métodos
2) os clientes vão invocar os métodos no utilizador (gets, sets…)

no servidor java RMi, vai pensar no que quero que seja invocado remotamente

no servidor, exemplo:
public interface RMiLight extends java.rmi.remote{
public void on() throws java.rmi.remoteException;
public void off() throws java.rmi.remoteException;
public void isOn() throws java.rmi.remoteException;
}

os métodos podem lançar para fora excepções que eu entender, em que, e é muito importante:
todos os métodos têm que lançar a expeção java.rmi.exception
as interfaces remotas extends java.rmi.remote

implementar o serviço, exemplo:

public class RMiLight extends java.rmi.unicastRemoteObject implements RMiLight{
public RMiLight()throws java.rmi.remote.exception{

}
public void on()throws java.rmi.remoteException {

}
}

em que:
public class RMiLight extends java.rmi.unicastRemoteObject implements RMiLight é um servidor base que não executa nada TCP
public RMiLight()throws java.rmi.remote.exception é um construtor obrigatorio. os construtores não aparecem na interface remota, mas os serviços remoto precisam de construtor que lançam excepções remotas (nem que seja vazio)

nos serviços tenho:
os métodos que pretendo que sejam invocados remotamente

só os métodos que fazem parte da interface remota é que precisam do RemoteException?
assim os outros métodos do serviço que não fazem parte da interface remota já não vão dar

assim ao criar uma instância da classe RMiLightBullImp no servidor vem que, exemplo do servidor:
public class void main(){
try{
//lançar uma thread em ciclo que cria +1 thread para cada cliente em paralelo que espera pedido de ligação
RMi bs = new RMiLightImp();
RemoteRef location = bs.getRef(); //não é necessário
string registry = “localhost”; //ip do registry e nó do serviço
if(args.lenght >1) { registry = args[0]; }
string registration = “rmi//” + registry + “/RMiLightBulb”; //registo do serviço
naming.rebind(registration, bs); //RMi e serviço
}catch(Remote Exception e){
}
}

apesar de chegar ao fim do main, ainda existe uma thread no modo de utilizador, e as aplicações em java só terminam se não existir mais threads de modo utilizador a decorrer

as aplicações agora só precisam de saber qual o IP onde está e qual o porto do servidor

naming.rebind(registration, bs);
em que:
se estabelece uma ligação TCP
no porto 1099 (porto de escuta do RMi registry)
manda-lhe uma margem para registar como o nome RMi Light bulb a referencia ao objecto Bs

rmi://192.10.10.10/xpb
o que faz quando se faz naming rebind

isto não estabelece uma ligação com um serviço
naming.lookup(rmi://192.10.10.10/xpb);

o naming.lookup no cliente para ele obter a referência para um serviço com este nome

quando se faz o lookup o que é feito é uma ligação TCP com qualquer coisa no IP no porto 1099 que é do registry e quero obter uma referência para um objecto com o nome xpb, esta referência tem interface e tem IP e porto

qual a diferença entre o método Bind e Rebind? (Bind e Rebind, tem a ver com tabelas no registry)
Com o rebind se existir é substituído senão existir cria
com o bind se não existir cria e se já existir cria uma excepção

no cliente o que é que faz o ON em bullbService.on(); sabendo que existiu
SErviceRmi bullBservice = (serviçoRmi) remoteSErvice

o cliente não faz um NEW local do objecto o que ele faz é um naming.lookup
no cliente depois vou ter um objecto que implementa a interface do serviço (on, off, …)
into é em sturb, e vai ser enviado ao fazer on, envia serializado a operação que tem que ser executada e que é o on, e o serviço recebe o pedido, executa e devolve o resutlado

qual é o aspecto comum entre proxy/sturb e o serviço?
é a interface, tem um conjunto de métodos coincidentes isto é, no serviço existe um on() e no sturb também existe um on() que na realidade envia uma mensagem para o outro lado para ligar

#cliente RMi

naming.lookup(registry);
isto faz uma ligação TCP com o RMi registry. faz um pedido do RMi registry e recebe um array de strings com o nome dos serviços registados
registry é o ip da maquina

relembrar que no RMi registry podemos solicitar:
lookup, pedir uma referÊncia para o objecto
bind/rebind, regista um serviço

#funcionalidades adicionais
para alunar uma referência que está na tabela
naming.unbind(“rmi://192.0.0.1/RMiLightBuld”)

para terminar no servidor e no main:
unexportObject(bulbSErvice, true);
em que bulbSErvice é o serviço

No servidor pode ser criado algo do tipo, prima qualquer tecla para terminar o serviço e com a inclusão do endpoint Object termina a thread em modo de utilizador
e só termina depois dos clientes serem atendidos, não é de forma abrupa, nas se for false termina logo tudo

o que significa?
endPoint(10.20,4,128.77:53561);
10.20,4,128.77 é o IP do serviço
53561 é o porto automático, criado pelos server socket
quando o cliente faz o lookup do registry obtêm uma referencia remota, o que se indica no lookup é o ip do registry e o porto (do registry) mas aqui é isto que eu obtenho

#funcionalidades adicionais
no servidor vou lançar o registry da maquina:
createRegistry
getRegistry

#invocação remota dos métodos
desenvolver aplicações remotas sem ter que se preocupar com sockets, sem usar o paradigma de troca de mensagens, sem usar TCP/UDP directamente
no cliente temos um Sturb (proxy), uma referência para o objecto remoto
no servidor existe o Skeleton, um servidor TPC, concorrente que recebe os pedisos, serializados, serialização binária do java.rmi, identifica qual o método que é para invocar, e argumentos, invoca e envia o resultado, e o método no cliente regressa e não é proxy

o que é que é comum entre o serviço (servidor) e a referência remota (Sturb, no cliente)?
é a interface implementada
o proxy não faz aquilo que é suposto o método fazerem, o que ele faz é pegar nos argumentos e envia para o servidor (Skeletton) que no servidor vai ser executado, que depois serializa e envia a resposta e o Sturb devolve a resposta ao cliente

quando o serviço é lançado (no servidor) ele regista-se no RMi registry (que é tipo um DNS) onde fica registado o IP e o porto onde pode ser encontrado o serviço

o cliente contacta o RMi registry à procura do serviço

o que acontece inernamente (por baixo) no cliente RMi quando ele faz so dos métodos, por exemplo em:
bulbSErvice.isOn()
é feito um pedido de envio
aguarda resposta
o pedido é serialziado
e é devolvida a resposta

situação de dois clientes acederem ao mesmo objecto ao mesmo tempo?
o cliente através do lookup contacta o registry (TCP, 1099) e envia o pedido para o que quer
o cliente depois recebe a referência remota do objecto, que tem a interface pretendida (métodos…) e também tem o ip e porto do serviço (serviço APi)
no servidor depois de contactado cria uma thread que vai cuidar desse cliente
e se existir outro cliente vai também ser o mesmo procedimento, e no serviço (servidor) é criada outra thread
assim eu tenho que verificar se é critico os acessos concorrentes, dois clientes têm acesso a um determinado serviço, estão a aceder ao mesmos erviço e mesmos recursos, então eu terei que colocar nas classes concretas/serviços o sincronized
por exemplo:
private boolean lightOn() sincronized;
pois pode ser alterada pelos vários clientes logo estes métodos têm que ser sincronized

#callBacks Rmi
callback são notoificações assincronas (o observador observável), por exemplo:

as vistas são actualizadas quando existem alterações no modelo, esta operação é o callback

quando existe um alteração no modle é notificada (avisada) a vista, por exemplo:

o cliente tem a referêcnai remota do serviço
o cliente quer saber sempre quando existe uma alteração em um membro do serviço
o cliente é um observador e o serviço um observavel
ambos estão na mesma maquina virtual
o servidor vai ter uma lista, coleção de referecnias para aplicações (observador/clientes) que esão interessados em ser notificados, é uma lista de sockets
do lado do cliente existe uma thread que está sempre à escuta, que recebe a mensagem e atualiza a vista

mas agora usamos objectos remotos, a lista no servidor vai ter coisas que implementam interfaces remotas nos clientes
os clientes passam a ter uma interface remota que vai ser usada pelo servidor
é muito importante perceber: os clientes implementam uma interface remota

o cliente vai logo terminar?
no main do cliente encontra-se:
tenho uma referencia
obtive a temperatura
crio o serviço (NEW…)
registo o sensor (temperature change…)
mas a aplicação do cliente não termina porque foi criado um objecto do tipo unicast object, que tem uma thread que está à escuta no server socket e que é um serviço

#protocolo HTPP em java
no HTTP temos um pedido (get) e uma resposta, através de uma ligação TCP
na resposta surge sempre um código de 3 digitos, e um cabeçalho e um corpo (opcional)

#URi
URi ou URL,
o URi, é um identificador
o URL, é um locator
ambos querem dizer a mesma coisa, servem para identificar recursos

o que é que isto identifica?
RMi://services.isec.pt/servicosacademicos

RMi registry, que é uma base de dados com uma tabela que tem nome e caminho remoto (dos sturbs)
em que servicosacademicos é nome do serviço

na tabela surgem referências remotas, do tipo javaRMi remote

com o método lookup, obtenho o valor correspondente aos servicosacademicos
com o método nbing, serve para apagar
com o método bing ou rebind, serve para acrescentar (bind) ou para substituir (rebind)

#campos cabeçalho
expansivel – campos prédifinidos
pedido – usando o método get, recurso, protocolo, mudança de linha
get / widget / xpto / 3 / http/1.1 \n\n
repsosta – http/1.1 200 ok
em que 200 é o código

se for feito um post serve para actualziar recursos nos ervidor, ou submeter autenticação

#java.net.url
o que faz o openStramÎnputStream in = myURL.openStream();
faz uma ligação TCP no porto adequado no URL, envia para lá um get com o ficheiro não identificado por omissão

#URL connection
prmite aceder aos códigos de estado das mensagens de resposta

#alguns métodos de autenticação HTTP
fazer um pedido HTTP, reebo uma resposta por parte do servidor
básico: em cada pedido tenho o login e password que vai no cabeçalho, e no cabeçalho vem
Authorization: basic usernamepassword
codificado em base 64, e é apenas uma forma de codificar

#token
o token depois de ser feita a autenticação é dado ao utilziador um token que só lhe pertence e esse token é unico, só do individuo
este é o token que permite ao utilziador fazer as suas operações depois do login

//—– perguntas de exame:
==1)
aparece este bocado de código:
PrintStream pout = new PrintStream(out);
pout.printl(new Java.util.date());
pout.flush();
1) o que faz este código?
o new java.util.date() é escrito no pout
2) concorda com a seguinte afirmação:
“este pedaço de código escreve no ecrã a hora atual seguida de uma mudança de linha”
Não, não é totalmente coreto, pode ser mas também pode não ser, porque o printStream está a receber um objeto do tipo outputStream e o outputstream não é só System.out, não é só fileOutPutStream, ele pode estar a escrever isto para um ficheiro, ou para o ecrã pode ser para um socket TCP, como ode ser um byteArray outpuStream (temos aqui uma questão de polimorfismo)

==2)
multicast(subclasse de DATAGRAMSOCKET)

em que:
multicast: quando queremos também receber as mensagens que são enviadas para o grupo
DATAGRAMSOCKET: se eu só pretendo enviar para um grupo de multicast é o envio de um DATAGRAMSOCKET UDP clássico, enviar para um determinado IP/porto

não existe nenhum servidor de gestão de grupos

==3)
as threads podem ser iniciadas em dois modos distintos:
modo por omissão, modo normal (modo utilizador) // bloqueante
modo através do daemon(serviço para correr em background) // não bloqueante

Uma aplicação em java termina quando já não existe qualquer, em que já não existem threads em modo utilizador activas.
As thraeds activas em modo de utilizador, mesmo chegando ao fim do main elas continuam activas, se forem as threads em modo daemon, chegada ao fim do main elas terminam

public class RunnableThreadDemo implements java.long.Runnable
{
public void run(){
SystemOut.println(“….”);
}
public static void main (String args[]){
System.Out.println(“…”);
Runnable run = new RunnableThreadDemo();
System.Out.println(“…”);
thread t1 = new Thread(run, “thread 1”); //run, é o nome da thread
System.Out.println(“…”);
thread t2 = new Thread (run, “trhead 2”); //run é o nome da thread
System.Out.println(“…”);
t1.start();
t2.start();
}
}

a diferença entre os dois modo de criar threads pode ser importante
assim o método II é melhor que o método I, já que posso criar várias threads baseadas no mesmo objecto runabble e elas vão partilhar os mesmos membros. posso assim ter várias threads concorrentes mas a trabalhar sobre os mesmos dados.
E outra vantagem é contornar uma das limitações do já de não haver herança múltipla

class ExtendThreadDemo extends java.long.thread // esta classe não pode estender outro tipo de objecto

==4)
threads, faz-se o new thread mas depois tem que se fazer o start,e  só depois do start o new cria um objecto que respresenta uma thread, mas o start lança de forma efectiva

==5)
complete o código, em que temos:
for(i = 0; i< nThreads; i++){
threads[i] = new ParallelPi(i+1, nThreads, nIntervals);
threads[i].start();
}

se eu estou a criar a minha thread com new ParallelPi, quer dizer que ParallelPi extends thread, se fosse implements runnable eu teria que ter um new Thread e em argumento um new ParallelPi
se existe um new ParallelPi e depois faço um start então é porque é extends thread e não implements Runnable

==6)
porque é que temos que usar drivers diferentes para bases de dados diferentes? se tiver que usar SQL, porque é que tenho que usar um driver diferente se tiver que usar ORACLE?
porque o protocolo de comunicação é diferente

==7)
um proxy que tem os métodos, e eu localmente tenho um objecto que tem os mesmos métodos
RPC é o inicio da história para o paradigma dos sistemas distribuídos (miiddleware)

os passo do RPC
passo1: o servidor fica a correr e vai-se registar na porta 111
passo2: o cliente solicita o porto do servidor
passo3: recebe a porta
passo4: faz o pedido
passo5: recebe a resposta

==8)
o que é que um serviço e um proxy têm em comum?
a interface, os métodos que implementam

==9)
porque razão é que o java RMi nas interfaces remotas tem que ter os argumentos e os resultados serializados?
porque o sistema, invocamos o método remoto e o que acontece é que é enviado um objecto que representa um pedido para o servidor, e o RMi faz a serialização dos objetos logo o pedido vai ter a identificação do método, etc, e assim tem que ser tudo serializado

==10)
só os métodos que fazem parte da interface remota é que precisam do RemoteException?
assim os outros métodos do serviço que não fazem parte da interface remota já não vão dar

==11)
naming.rebind(registration, bs);
em que:
se estabelece uma ligação TCP
no porto 1099 (porto de escuta do RMi registry)
manda-lhe uma margem para registar como o nome RMi Light bulb a referencia ao objecto Bs

==12)
rmi://192.10.10.10/xpb
o que faz quando se faz naming rebind

isto não estabelece uma ligação com um serviço
naming.lookup(rmi://192.10.10.10/xpb);

o naming.lookup no cliente para ele obter a referência para um serviço com este nome

quando se faz o lookup o que é feito é uma ligação TCP com qualquer coisa no IP no porto 1099 que é do registry e quero obter uma referência para um objecto com o nome xpb, esta referência tem interface e tem IP e porto

==13)
qual a diferença entre o método Bind e Rebind? (Bind e Rebind, tem a ver com tabelas no registry)
Com o rebind se existir é substituído senão existir ria
com o bind se não existir cria e se já existir cria uma excepção

==14)
no cliente o que é que faz o ON em bullbService.on(); sabendo que existiu
SErviceRmi bullBservice = (serviçoRmi) remoteSErvice

o cliente não faz um NEW local do objecto o que ele faz é um naming.lookup
no cliente depois vou ter um objecto que implementa a interface do serviço (on, off, …)
into é em sturb, e vai ser enviado ao fazer on, envia serializado a operação que tem que ser executada e que é o on, e o serviço recebe o pedido, executa e devolve o resutlado

==15)
qual é o aspecto comum entre proxy/sturb e o serviço?
é a interface, tem um conjunto de métodos coincidentes isto é, no serviço existe um on() e no sturb também existe um on() que na realidade envia uma mensagem para o outro lado para ligar

==16)
o que significa?
endPoint(10.20,4,128.77:53561);
10.20,4,128.77 é o IP do serviço
53561 é o porto automático, criado pelos server socket
quando o cliente faz o lookup do registry obtêm uma eferencia remota, o que se indica no lookup é o ip do registry e o porto (do registry) mas aqui é isto que eu obtenho

==17)
o que é que é comum entre o serviço (servidor) e a referência remota (Sturb, no cliente)?
é a interface implementada
o proxy não faz aquilo que é suposto o método fazerem, o que ele faz é pegar nos argumentos e envia para o servidor (Skeletton) que no servidor vai ser executado, que depois serializa e envia a resposta e o Sturb devolve a resposta ao cliente

quando o serviço é lançado (no servidor) ele regista-se no RMi registry (que é tipo um DNS) onde fica registado o IP e o porto onde pode ser encontrado o serviço

==18)
o que acontece inernamente (por baixo) no cliente RMi quando ele faz so dos métodos, por exemplo em:
bulbSErvice.isOn()
é feito um pedido de envio
aguarda resposta
o pedido é serialziado
e é devolvida a resposta

==19)
situação de dois clientes acederem ao mesmo objecto ao mesmo tempo?
o cliente através do lookup contacta o registry (TCP, 1099) e envia o pedido para o que quer
o cliente depois recebe a referência remota do objecto, que tem a interface pretendida (métodos…) e também tem o ip e porto do serviço (serviço APi)
no servidor depois de contactado cria uma thread que vai cuidar desse cliente
e se existir outro cliente vai também ser o mesmo procedimento, e no serviço (servidor) é criada outra thread
assim eu tenho que verificar se é critico os acessos concorrentes, dois clientes têm acesso a um determinado serviço, estão a aceder ao mesmos erviço e mesmos recursos, então eu terei que colocar nas classes concretas/serviços o sincronized
por exemplo:
private boolean lightOn() sincronized;
pois pode ser alterada pelos vários clientes logo estes métodos têm que ser sincronized

==20)
callbacks RMi
o cliente vai logo terminar?
no main do cliente encontra-se:
tenho uma referencia
obtive a temperatura
crio o serviço (NEW…)
registo o sensor (temperature change…)
mas a aplicação do cliente não termina porque foi criado um objecto do tipo unicast object, que tem uma thread que está à escuta no server socket e que é um serviço

==21)
o que é que isto identifica?
RMi://services.isec.pt/servicosacademicos

RMi registry, que é uma base de dados com uma tabela que tem nome e caminho remoto (dos sturbs)
em que servicosacademicos é nome do serviço

na tabela surgem referências remotas, do tipo javaRMi remote

com o método lookup, obtenho o valor correspondente aos servicosacademicos
com o método nbing, serve para apagar
com o método bing ou rebind, serve para acrescentar (bind) ou para substituir (rebind)

==22)
o que faz o openStramÎnputStream in = myURL.openStream();
faz uma ligação TCP no porto adequado no URL, envia para lá um get com o ficheiro não identificado por omissão

Tags : , ,